PeachFullzZ's Thailand Wiki peachfullzzthailandwiki https://peachfullzzthailand.miraheze.org/wiki/%E0%B8%AB%E0%B8%99%E0%B9%89%E0%B8%B2%E0%B8%AB%E0%B8%A5%E0%B8%B1%E0%B8%81 MediaWiki 1.40.1 first-letter สื่อ พิเศษ พูดคุย ผู้ใช้ คุยกับผู้ใช้ PeachFullzZ's Thailand Wiki คุยเรื่องPeachFullzZ's Thailand Wiki ไฟล์ คุยเรื่องไฟล์ มีเดียวิกิ คุยเรื่องมีเดียวิกิ แม่แบบ คุยเรื่องแม่แบบ วิธีใช้ คุยเรื่องวิธีใช้ หมวดหมู่ คุยเรื่องหมวดหมู่ มอดูล คุยเรื่องมอดูล หน้าหลัก 0 1 1 2023-10-04T18:49:51Z MediaWiki default 1 Create main page wikitext text/x-wiki __NOTOC__ == Welcome to {{SITENAME}}! == This Main Page was created automatically and it seems it hasn't been replaced yet. === For the bureaucrat(s) of this wiki === Hello, and welcome to your new wiki! Thank you for choosing Miraheze for the hosting of your wiki, we hope you will enjoy our hosting. You can immediately start working on your wiki or whenever you want. Need help? No problem! We will help you with your wiki as needed. To start, try checking out these helpful links: * [[mw:Special:MyLanguage/Help:Contents|MediaWiki guide]] (e.g. navigation, editing, deleting pages, blocking users) * [[meta:Special:MyLanguage/FAQ|Miraheze FAQ]] * [[meta:Special:MyLanguage/Request features|Request settings changes on your wiki]]. (Extensions, Skin and Logo/Favicon changes should be done through [[Special:ManageWiki]] on your wiki, see [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] for more information.) ==== I still don't understand X! ==== Well, that's no problem. Even if something isn't explained in the documentation/FAQ, we are still happy to help you. You can find us here: * [[meta:Special:MyLanguage/Help center|On our own Miraheze wiki]] * On [[phab:|Phabricator]] * On [https://miraheze.org/discord Discord] * On IRC in #miraheze on irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze webchat]) === For visitors of this wiki === Hello, the default Main Page of this wiki (this page) has not yet been replaced by the bureaucrat(s) of this wiki. The bureaucrat(s) might still be working on a Main Page, so please check again later! 21236ac3f8d65e5563b6da6b70815ca6bf1e6616 อนาวิน สุขเกษมอดิศักดิ์ 0 2 2 2023-10-05T07:58:07Z PeachFullzZ 2 เริ่มต้นเนื้อหา 'อนาวิน สุขเกษมอดิศักดิ์' wikitext text/x-wiki '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย 50e451ec87d206d6ef557bc70099dc7b5c74180c 16 2 2023-10-05T09:51:03Z PeachFullzZ 2 /* งานการเมือง */ wikitext text/x-wiki '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย === หลังการเลือกนายกและการลาออก === ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย aee9c863afebfda5d8b1877402de863576bcc69b 17 16 2023-10-05T10:00:24Z PeachFullzZ 2 /* งานการเมือง */ wikitext text/x-wiki '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย 71d0c372c2666f6f923c7cb78510faed018e7c0f 40 17 2023-10-05T11:15:21Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | image = | caption = | office1 = [[สภานิติบัญญัติแห่งชาติ|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start1 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | term_end1 = | constituency1 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office2 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = พ.ศ. 2566 | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2020|3|14|2023|9|15}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = {{วันเกิด-อายุ|2523|9|5}}<ref name=birth/> | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย 98e891617e9b55b85d5d59a7c5987b04f344a68d 45 40 2023-10-05T11:23:31Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | image = | caption = | office1 = [[สภานิติบัญญัติแห่งชาติ|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start1 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | term_end1 = | parliamentarygroup1 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office2 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = พ.ศ. 2566 | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2020|3|14|2023|9|15}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = {{วันเกิด-อายุ|2523|9|5}} | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย bbe3c6a0b7837ee434b4e573cd582136550cf2e6 48 45 2023-10-05T11:36:33Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = | caption = | office1 = [[สภานิติบัญญัติแห่งชาติ|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start1 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | term_end1 = | parliamentarygroup1 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office2 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = พ.ศ. 2566 | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2020|3|14|2023|9|15}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = {{วันเกิด-อายุ|2523|9|5}} | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย c2fd49186aaccc196210bbe8fcd96a145c00c3ad แม่แบบ:กล่องคำพูด 10 3 3 2023-10-05T08:09:24Z PeachFullzZ 2 สร้างแม่แบบ wikitext text/x-wiki <templatestyles src="แม่แบบ:กล่องคำพูด/styles.css" /><div class="quotebox pullquote {{#switch: {{lc:{{{align|}}}}} | center = centered | left = floatleft | none = | floatright }} {{{class|}}}" style=" {{#if:{{{width|}}} |width:{{{width}}};}} {{#ifeq:{{{border}}}|none|border:none;|{{#if:{{{border|}}}|border-width: {{{border}}}}};}} {{#if:{{{fontsize|}}}|font-size: {{{fontsize}}};}} {{#if:{{{bgcolor|}}}|background-color: {{#ifeq:{{{bgcolor|}}}|none|transparent|{{{bgcolor}}}}};}} {{{style|}}}"> {{#if:{{{title|}}} |<div class="quotebox-title {{{tclass|}}}" style=" {{#if:{{{title_bg|{{{bgcolor|}}}}}}|background-color: {{#ifeq:{{{title_bg|{{{bgcolor}}}}}}|none|transparent|{{{title_bg|{{{bgcolor}}}}}}}};}} {{#if:{{{title_fnt|}}}|color: {{{title_fnt}}};}} {{{tstyle|}}}">{{{title}}}</div> }} <blockquote class="quotebox-quote {{main other||{{#if:{{{quoted|}}}|quoted}}}} {{#switch: {{lc:{{{qalign|{{{halign|left}}}}}}}} |right = right-aligned |center = center-aligned |left-aligned }} {{{qclass|}}}" style=" {{{qstyle|}}}"> {{{text|{{{content|{{{quotetext|{{{quote|{{{1|<includeonly>{{error|ข้อผิดพลาด: ไม่มีข้อความในการทำกล่องคำพูด (หรือเครื่องหมายเท่ากับที่ใช้ในอาร์กิวเมนต์จริงจะถูกเข้าใจว่าเป็นพารามิเตอร์ที่ไม่มีชื่อ)}}</includeonly><noinclude>{{lorem ipsum}}</noinclude>}}}}}}}}}}}}}}} </blockquote> {{#if:{{{author|{{{source|}}}}}}{{{2|}}}{{{3|}}}|<cite class="{{#switch: {{lc:{{{salign|{{{qalign|{{{halign|left}}} }}} }}} }} |right = right-aligned |center = center-aligned |left-aligned }}" style="{{{sstyle|}}}"><!--ต้องลบเครื่องหมายขีดกลางที่แทรกอยู่ด้วยตนเอง ออกจากการใช้แม่แบบ จากนั้นจึงเปิดใช้งาน:--><!--—&thinsp;-->{{{author|{{{2|}}}}}}{{#if:{{{author|}}}{{{2|}}}|{{#if:{{{source|}}}{{{3|}}}|<!--แสดงเครื่องหมายจุลภาค-เว้นวรรค เฉพาะเมื่อมีพารามิเตอร์อ้างอิงทั้งสองรายการเท่านั้น-->,&#32;}}}}{{{source|{{{3|}}}}}}</cite>}} </div>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[หมวดหมู่:หน้าที่ใช้กล่องคำพูดซึ่งมีพารามิเตอร์ที่ไม่รู้จัก|_VALUE_{{PAGENAME}}]]}}|preview=หน้าที่ใช้ [[แม่แบบ:กล่องคำพูด]] ซึ่งมีพารามิเตอร์ที่ไม่รู้จัก "_VALUE_"|ignoreblank=y| 1 | 2 | 3 | align | author | bgcolor | border | class | content | fontsize | halign | qalign | qclass | qstyle | quote | quoted | quotetext | salign | source | sstyle | style | tclass | text | title | title_bg | title_fnt | tstyle | width }}<noinclude> {{เอกสารประกอบ}} </noinclude> 66d45930271cee3df51956029f7ca0b6e7a2c674 แม่แบบ:!! 10 4 4 2023-10-05T08:11:41Z PeachFullzZ 2 สร้างหน้าด้วย "||<noinclude> {{เอกสารประกอบ}} </noinclude>" wikitext text/x-wiki ||<noinclude> {{เอกสารประกอบ}} </noinclude> 23dd5fa6ab5daff82dc33c89fb872e63603dcc1d แม่แบบ:เอกสารประกอบ 10 5 5 2023-10-05T08:14:23Z PeachFullzZ 2 สร้างหน้าด้วย "{{#invoke:documentation|main|_content={{ {{#invoke:documentation|contentTitle}}}}}}<noinclude> <!-- เพิ่มหมวดหมู่ในหน้าย่อย /doc --> </noinclude>" wikitext text/x-wiki {{#invoke:documentation|main|_content={{ {{#invoke:documentation|contentTitle}}}}}}<noinclude> <!-- เพิ่มหมวดหมู่ในหน้าย่อย /doc --> </noinclude> 8d37cc4553ff3521468afb467c3daec5c11364b2 มอดูล:Documentation 828 6 6 2023-10-05T08:16:57Z PeachFullzZ 2 สร้างหน้าด้วย "-- This module implements {{documentation}}. -- Get required modules. local getArgs = require('Module:Arguments').getArgs -- Get the config table. local cfg = mw.loadData('Module:Documentation/config') local p = {} -- Often-used functions. local ugsub = mw.ustring.gsub local format = mw.ustring.format ---------------------------------------------------------------------------- -- Helper functions -- -- These are defined as local functions, but..." Scribunto text/plain -- This module implements {{documentation}}. -- Get required modules. local getArgs = require('Module:Arguments').getArgs -- Get the config table. local cfg = mw.loadData('Module:Documentation/config') local p = {} -- Often-used functions. local ugsub = mw.ustring.gsub local format = mw.ustring.format ---------------------------------------------------------------------------- -- Helper functions -- -- These are defined as local functions, but are made available in the p -- table for testing purposes. ---------------------------------------------------------------------------- local function message(cfgKey, valArray, expectType) --[[ -- Gets a message from the cfg table and formats it if appropriate. -- The function raises an error if the value from the cfg table is not -- of the type expectType. The default type for expectType is 'string'. -- If the table valArray is present, strings such as $1, $2 etc. in the -- message are substituted with values from the table keys [1], [2] etc. -- For example, if the message "foo-message" had the value 'Foo $2 bar $1.', -- message('foo-message', {'baz', 'qux'}) would return "Foo qux bar baz." --]] local msg = cfg[cfgKey] expectType = expectType or 'string' if type(msg) ~= expectType then error('message: type error in message cfg.' .. cfgKey .. ' (' .. expectType .. ' expected, got ' .. type(msg) .. ')', 2) end if not valArray then return msg end local function getMessageVal(match) match = tonumber(match) return valArray[match] or error('message: no value found for key $' .. match .. ' in message cfg.' .. cfgKey, 4) end return ugsub(msg, '$([1-9][0-9]*)', getMessageVal) end p.message = message local function makeWikilink(page, display) if display then return format('[[%s|%s]]', page, display) else return format('[[%s]]', page) end end p.makeWikilink = makeWikilink local function makeCategoryLink(cat, sort) local catns = mw.site.namespaces[14].name return makeWikilink(catns .. ':' .. cat, sort) end p.makeCategoryLink = makeCategoryLink local function makeUrlLink(url, display) return format('[%s %s]', url, display) end p.makeUrlLink = makeUrlLink local function makeToolbar(...) local ret = {} local lim = select('#', ...) if lim < 1 then return nil end for i = 1, lim do ret[#ret + 1] = select(i, ...) end -- 'documentation-toolbar' return format( '<span class="%s">(%s)</span>', message('toolbar-class'), table.concat(ret, ' &#124; ') ) end p.makeToolbar = makeToolbar ---------------------------------------------------------------------------- -- Argument processing ---------------------------------------------------------------------------- local function makeInvokeFunc(funcName) return function (frame) local args = getArgs(frame, { valueFunc = function (key, value) if type(value) == 'string' then value = value:match('^%s*(.-)%s*$') -- Remove whitespace. if key == 'heading' or value ~= '' then return value else return nil end else return value end end }) return p[funcName](args) end end ---------------------------------------------------------------------------- -- Entry points ---------------------------------------------------------------------------- function p.nonexistent(frame) if mw.title.getCurrentTitle().subpageText == 'testcases' then return frame:expandTemplate{title = 'module test cases notice'} else return p.main(frame) end end p.main = makeInvokeFunc('_main') function p._main(args) --[[ -- This function defines logic flow for the module. -- @args - table of arguments passed by the user --]] local env = p.getEnvironment(args) local root = mw.html.create() root :wikitext(p._getModuleWikitext(args, env)) :wikitext(p.protectionTemplate(env)) :wikitext(p.sandboxNotice(args, env)) :tag('div') -- 'documentation-container' :addClass(message('container')) :attr('role', 'complementary') :attr('aria-labelledby', args.heading ~= '' and 'documentation-heading' or nil) :attr('aria-label', args.heading == '' and 'Documentation' or nil) :newline() :tag('div') -- 'documentation' :addClass(message('main-div-classes')) :newline() :wikitext(p._startBox(args, env)) :wikitext(p._content(args, env)) :tag('div') -- 'documentation-clear' :addClass(message('clear')) :done() :newline() :done() :wikitext(p._endBox(args, env)) :done() :wikitext(p.addTrackingCategories(env)) -- 'Module:Documentation/styles.css' return mw.getCurrentFrame():extensionTag ( 'templatestyles', '', {src=cfg['templatestyles'] }) .. tostring(root) end ---------------------------------------------------------------------------- -- Environment settings ---------------------------------------------------------------------------- function p.getEnvironment(args) --[[ -- Returns a table with information about the environment, including title -- objects and other namespace- or path-related data. -- @args - table of arguments passed by the user -- -- Title objects include: -- env.title - the page we are making documentation for (usually the current title) -- env.templateTitle - the template (or module, file, etc.) -- env.docTitle - the /doc subpage. -- env.sandboxTitle - the /sandbox subpage. -- env.testcasesTitle - the /testcases subpage. -- -- Data includes: -- env.protectionLevels - the protection levels table of the title object. -- env.subjectSpace - the number of the title's subject namespace. -- env.docSpace - the number of the namespace the title puts its documentation in. -- env.docpageBase - the text of the base page of the /doc, /sandbox and /testcases pages, with namespace. -- env.compareUrl - URL of the Special:ComparePages page comparing the sandbox with the template. -- -- All table lookups are passed through pcall so that errors are caught. If an error occurs, the value -- returned will be nil. --]] local env, envFuncs = {}, {} -- Set up the metatable. If triggered we call the corresponding function in the envFuncs table. The value -- returned by that function is memoized in the env table so that we don't call any of the functions -- more than once. (Nils won't be memoized.) setmetatable(env, { __index = function (t, key) local envFunc = envFuncs[key] if envFunc then local success, val = pcall(envFunc) if success then env[key] = val -- Memoise the value. return val end end return nil end }) function envFuncs.title() -- The title object for the current page, or a test page passed with args.page. local title local titleArg = args.page if titleArg then title = mw.title.new(titleArg) else title = mw.title.getCurrentTitle() end return title end function envFuncs.templateTitle() --[[ -- The template (or module, etc.) title object. -- Messages: -- 'sandbox-subpage' --> 'sandbox' -- 'testcases-subpage' --> 'testcases' --]] local subjectSpace = env.subjectSpace local title = env.title local subpage = title.subpageText if subpage == message('sandbox-subpage') or subpage == message('testcases-subpage') then return mw.title.makeTitle(subjectSpace, title.baseText) else return mw.title.makeTitle(subjectSpace, title.text) end end function envFuncs.docTitle() --[[ -- Title object of the /doc subpage. -- Messages: -- 'doc-subpage' --> 'doc' --]] local title = env.title local docname = args[1] -- User-specified doc page. local docpage if docname then docpage = docname else docpage = env.docpageBase .. '/' .. message('doc-subpage') end return mw.title.new(docpage) end function envFuncs.sandboxTitle() --[[ -- Title object for the /sandbox subpage. -- Messages: -- 'sandbox-subpage' --> 'sandbox' --]] return mw.title.new(env.docpageBase .. '/' .. message('sandbox-subpage')) end function envFuncs.testcasesTitle() --[[ -- Title object for the /testcases subpage. -- Messages: -- 'testcases-subpage' --> 'testcases' --]] return mw.title.new(env.docpageBase .. '/' .. message('testcases-subpage')) end function envFuncs.protectionLevels() -- The protection levels table of the title object. return env.title.protectionLevels end function envFuncs.subjectSpace() -- The subject namespace number. return mw.site.namespaces[env.title.namespace].subject.id end function envFuncs.docSpace() -- The documentation namespace number. For most namespaces this is the -- same as the subject namespace. However, pages in the Article, File, -- MediaWiki or Category namespaces must have their /doc, /sandbox and -- /testcases pages in talk space. local subjectSpace = env.subjectSpace if subjectSpace == 0 or subjectSpace == 6 or subjectSpace == 8 or subjectSpace == 14 then return subjectSpace + 1 else return subjectSpace end end function envFuncs.docpageBase() -- The base page of the /doc, /sandbox, and /testcases subpages. -- For some namespaces this is the talk page, rather than the template page. local templateTitle = env.templateTitle local docSpace = env.docSpace local docSpaceText = mw.site.namespaces[docSpace].name -- Assemble the link. docSpace is never the main namespace, so we can hardcode the colon. return docSpaceText .. ':' .. templateTitle.text end function envFuncs.compareUrl() -- Diff link between the sandbox and the main template using [[Special:ComparePages]]. local templateTitle = env.templateTitle local sandboxTitle = env.sandboxTitle if templateTitle.exists and sandboxTitle.exists then local compareUrl = mw.uri.canonicalUrl( 'Special:ComparePages', { page1 = templateTitle.prefixedText, page2 = sandboxTitle.prefixedText} ) return tostring(compareUrl) else return nil end end return env end ---------------------------------------------------------------------------- -- Auxiliary templates ---------------------------------------------------------------------------- p.getModuleWikitext = makeInvokeFunc('_getModuleWikitext') function p._getModuleWikitext(args, env) local currentTitle = mw.title.getCurrentTitle() if currentTitle.contentModel ~= 'Scribunto' then return end pcall(require, currentTitle.prefixedText) -- if it fails, we don't care local moduleWikitext = package.loaded["Module:Module wikitext"] if moduleWikitext then return moduleWikitext.main() end end function p.sandboxNotice(args, env) --[=[ -- Generates a sandbox notice for display above sandbox pages. -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- -- Messages: -- 'sandbox-notice-image' --> '[[File:Sandbox.svg|50px|alt=|link=]]' -- 'sandbox-notice-blurb' --> 'This is the $1 for $2.' -- 'sandbox-notice-diff-blurb' --> 'This is the $1 for $2 ($3).' -- 'sandbox-notice-pagetype-template' --> '[[Wikipedia:Template test cases|template sandbox]] page' -- 'sandbox-notice-pagetype-module' --> '[[Wikipedia:Template test cases|module sandbox]] page' -- 'sandbox-notice-pagetype-other' --> 'sandbox page' -- 'sandbox-notice-compare-link-display' --> 'diff' -- 'sandbox-notice-testcases-blurb' --> 'See also the companion subpage for $1.' -- 'sandbox-notice-testcases-link-display' --> 'test cases' -- 'sandbox-category' --> 'Template sandboxes' --]=] local title = env.title local sandboxTitle = env.sandboxTitle local templateTitle = env.templateTitle local subjectSpace = env.subjectSpace if not (subjectSpace and title and sandboxTitle and templateTitle and mw.title.equals(title, sandboxTitle)) then return nil end -- Build the table of arguments to pass to {{ombox}}. We need just two fields, "image" and "text". local omargs = {} omargs.image = message('sandbox-notice-image') -- Get the text. We start with the opening blurb, which is something like -- "This is the template sandbox for [[Template:Foo]] (diff)." local text = '' local pagetype if subjectSpace == 10 then pagetype = message('sandbox-notice-pagetype-template') elseif subjectSpace == 828 then pagetype = message('sandbox-notice-pagetype-module') else pagetype = message('sandbox-notice-pagetype-other') end local templateLink = makeWikilink(templateTitle.prefixedText) local compareUrl = env.compareUrl if compareUrl then local compareDisplay = message('sandbox-notice-compare-link-display') local compareLink = makeUrlLink(compareUrl, compareDisplay) text = text .. message('sandbox-notice-diff-blurb', {pagetype, templateLink, compareLink}) else text = text .. message('sandbox-notice-blurb', {pagetype, templateLink}) end -- Get the test cases page blurb if the page exists. This is something like -- "See also the companion subpage for [[Template:Foo/testcases|test cases]]." local testcasesTitle = env.testcasesTitle if testcasesTitle and testcasesTitle.exists then if testcasesTitle.contentModel == "Scribunto" then local testcasesLinkDisplay = message('sandbox-notice-testcases-link-display') local testcasesRunLinkDisplay = message('sandbox-notice-testcases-run-link-display') local testcasesLink = makeWikilink(testcasesTitle.prefixedText, testcasesLinkDisplay) local testcasesRunLink = makeWikilink(testcasesTitle.talkPageTitle.prefixedText, testcasesRunLinkDisplay) text = text .. '<br />' .. message('sandbox-notice-testcases-run-blurb', {testcasesLink, testcasesRunLink}) else local testcasesLinkDisplay = message('sandbox-notice-testcases-link-display') local testcasesLink = makeWikilink(testcasesTitle.prefixedText, testcasesLinkDisplay) text = text .. '<br />' .. message('sandbox-notice-testcases-blurb', {testcasesLink}) end end -- Add the sandbox to the sandbox category. omargs.text = text .. makeCategoryLink(message('sandbox-category')) -- 'documentation-clear' return '<div class="' .. message('clear') .. '"></div>' .. require('Module:Message box').main('ombox', omargs) end function p.protectionTemplate(env) -- Generates the padlock icon in the top right. -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- Messages: -- 'protection-template' --> 'pp-template' -- 'protection-template-args' --> {docusage = 'yes'} local protectionLevels = env.protectionLevels if not protectionLevels then return nil end local editProt = protectionLevels.edit and protectionLevels.edit[1] local moveProt = protectionLevels.move and protectionLevels.move[1] if editProt then -- The page is edit-protected. return require('Module:Protection banner')._main{ message('protection-reason-edit'), small = true } elseif moveProt and moveProt ~= 'autoconfirmed' then -- The page is move-protected but not edit-protected. Exclude move -- protection with the level "autoconfirmed", as this is equivalent to -- no move protection at all. return require('Module:Protection banner')._main{ action = 'move', small = true } else return nil end end ---------------------------------------------------------------------------- -- Start box ---------------------------------------------------------------------------- p.startBox = makeInvokeFunc('_startBox') function p._startBox(args, env) --[[ -- This function generates the start box. -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- -- The actual work is done by p.makeStartBoxLinksData and p.renderStartBoxLinks which make -- the [view] [edit] [history] [purge] links, and by p.makeStartBoxData and p.renderStartBox -- which generate the box HTML. --]] env = env or p.getEnvironment(args) local links local content = args.content if not content or args[1] then -- No need to include the links if the documentation is on the template page itself. local linksData = p.makeStartBoxLinksData(args, env) if linksData then links = p.renderStartBoxLinks(linksData) end end -- Generate the start box html. local data = p.makeStartBoxData(args, env, links) if data then return p.renderStartBox(data) else -- User specified no heading. return nil end end function p.makeStartBoxLinksData(args, env) --[[ -- Does initial processing of data to make the [view] [edit] [history] [purge] links. -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- -- Messages: -- 'view-link-display' --> 'view' -- 'edit-link-display' --> 'edit' -- 'history-link-display' --> 'history' -- 'purge-link-display' --> 'purge' -- 'module-preload' --> 'Template:Documentation/preload-module-doc' -- 'docpage-preload' --> 'Template:Documentation/preload' -- 'create-link-display' --> 'create' --]] local subjectSpace = env.subjectSpace local title = env.title local docTitle = env.docTitle if not title or not docTitle then return nil end if docTitle.isRedirect then docTitle = docTitle.redirectTarget end -- Create link if /doc doesn't exist. local preload = args.preload if not preload then if subjectSpace == 828 then -- Module namespace preload = message('module-preload') else preload = message('docpage-preload') end end return { title = title, docTitle = docTitle, -- View, display, edit, and purge links if /doc exists. viewLinkDisplay = message('view-link-display'), editLinkDisplay = message('edit-link-display'), historyLinkDisplay = message('history-link-display'), purgeLinkDisplay = message('purge-link-display'), preload = preload, createLinkDisplay = message('create-link-display') } end function p.renderStartBoxLinks(data) --[[ -- Generates the [view][edit][history][purge] or [create][purge] links from the data table. -- @data - a table of data generated by p.makeStartBoxLinksData --]] local docTitle = data.docTitle -- yes, we do intend to purge the template page on which the documentation appears local purgeLink = makeWikilink("Special:Purge/" .. data.title.prefixedText, data.purgeLinkDisplay) if docTitle.exists then local viewLink = makeWikilink(docTitle.prefixedText, data.viewLinkDisplay) local editLink = makeWikilink("Special:EditPage/" .. docTitle.prefixedText, data.editLinkDisplay) local historyLink = makeWikilink("Special:PageHistory/" .. docTitle.prefixedText, data.historyLinkDisplay) return "&#91;" .. viewLink .. "&#93; &#91;" .. editLink .. "&#93; &#91;" .. historyLink .. "&#93; &#91;" .. purgeLink .. "&#93;" else local createLink = makeUrlLink(docTitle:canonicalUrl{action = 'edit', preload = data.preload}, data.createLinkDisplay) return "&#91;" .. createLink .. "&#93; &#91;" .. purgeLink .. "&#93;" end return ret end function p.makeStartBoxData(args, env, links) --[=[ -- Does initial processing of data to pass to the start-box render function, p.renderStartBox. -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- @links - a string containing the [view][edit][history][purge] links - could be nil if there's an error. -- -- Messages: -- 'documentation-icon-wikitext' --> '[[File:Test Template Info-Icon - Version (2).svg|50px|link=|alt=]]' -- 'template-namespace-heading' --> 'Template documentation' -- 'module-namespace-heading' --> 'Module documentation' -- 'file-namespace-heading' --> 'Summary' -- 'other-namespaces-heading' --> 'Documentation' -- 'testcases-create-link-display' --> 'create' --]=] local subjectSpace = env.subjectSpace if not subjectSpace then -- Default to an "other namespaces" namespace, so that we get at least some output -- if an error occurs. subjectSpace = 2 end local data = {} -- Heading local heading = args.heading -- Blank values are not removed. if heading == '' then -- Don't display the start box if the heading arg is defined but blank. return nil end if heading then data.heading = heading elseif subjectSpace == 10 then -- Template namespace data.heading = message('documentation-icon-wikitext') .. ' ' .. message('template-namespace-heading') elseif subjectSpace == 828 then -- Module namespace data.heading = message('documentation-icon-wikitext') .. ' ' .. message('module-namespace-heading') elseif subjectSpace == 6 then -- File namespace data.heading = message('file-namespace-heading') else data.heading = message('other-namespaces-heading') end -- Heading CSS local headingStyle = args['heading-style'] if headingStyle then data.headingStyleText = headingStyle else -- 'documentation-heading' data.headingClass = message('main-div-heading-class') end -- Data for the [view][edit][history][purge] or [create] links. if links then -- 'mw-editsection-like plainlinks' data.linksClass = message('start-box-link-classes') data.links = links end return data end function p.renderStartBox(data) -- Renders the start box html. -- @data - a table of data generated by p.makeStartBoxData. local sbox = mw.html.create('div') sbox -- 'documentation-startbox' :addClass(message('start-box-class')) :newline() :tag('span') :addClass(data.headingClass) :attr('id', 'documentation-heading') :cssText(data.headingStyleText) :wikitext(data.heading) local links = data.links if links then sbox:tag('span') :addClass(data.linksClass) :attr('id', data.linksId) :wikitext(links) end return tostring(sbox) end ---------------------------------------------------------------------------- -- Documentation content ---------------------------------------------------------------------------- p.content = makeInvokeFunc('_content') function p._content(args, env) -- Displays the documentation contents -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment env = env or p.getEnvironment(args) local docTitle = env.docTitle local content = args.content if not content and docTitle and docTitle.exists then content = args._content or mw.getCurrentFrame():expandTemplate{title = docTitle.prefixedText} end -- The line breaks below are necessary so that "=== Headings ===" at the start and end -- of docs are interpreted correctly. return '\n' .. (content or '') .. '\n' end p.contentTitle = makeInvokeFunc('_contentTitle') function p._contentTitle(args, env) env = env or p.getEnvironment(args) local docTitle = env.docTitle if not args.content and docTitle and docTitle.exists then return docTitle.prefixedText else return '' end end ---------------------------------------------------------------------------- -- End box ---------------------------------------------------------------------------- p.endBox = makeInvokeFunc('_endBox') function p._endBox(args, env) --[=[ -- This function generates the end box (also known as the link box). -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- --]=] -- Get environment data. env = env or p.getEnvironment(args) local subjectSpace = env.subjectSpace local docTitle = env.docTitle if not subjectSpace or not docTitle then return nil end -- Check whether we should output the end box at all. Add the end -- box by default if the documentation exists or if we are in the -- user, module or template namespaces. local linkBox = args['link box'] if linkBox == 'off' or not ( docTitle.exists or subjectSpace == 2 or subjectSpace == 828 or subjectSpace == 10 ) then return nil end -- Assemble the link box. local text = '' if linkBox then text = text .. linkBox else text = text .. (p.makeDocPageBlurb(args, env) or '') -- "This documentation is transcluded from [[Foo]]." if subjectSpace == 2 or subjectSpace == 10 or subjectSpace == 828 then -- We are in the user, template or module namespaces. -- Add sandbox and testcases links. -- "Editors can experiment in this template's sandbox and testcases pages." text = text .. (p.makeExperimentBlurb(args, env) or '') .. '<br />' if not args.content and not args[1] then -- "Please add categories to the /doc subpage." -- Don't show this message with inline docs or with an explicitly specified doc page, -- as then it is unclear where to add the categories. text = text .. (p.makeCategoriesBlurb(args, env) or '') end text = text .. ' ' .. (p.makeSubpagesBlurb(args, env) or '') --"Subpages of this template" end end local box = mw.html.create('div') -- 'documentation-metadata' box:attr('role', 'note') :addClass(message('end-box-class')) -- 'plainlinks' :addClass(message('end-box-plainlinks')) :wikitext(text) :done() return '\n' .. tostring(box) end function p.makeDocPageBlurb(args, env) --[=[ -- Makes the blurb "This documentation is transcluded from [[Template:Foo]] (edit, history)". -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- -- Messages: -- 'edit-link-display' --> 'edit' -- 'history-link-display' --> 'history' -- 'transcluded-from-blurb' --> -- 'The above [[Wikipedia:Template documentation|documentation]] -- is [[Help:Transclusion|transcluded]] from $1.' -- 'module-preload' --> 'Template:Documentation/preload-module-doc' -- 'create-link-display' --> 'create' -- 'create-module-doc-blurb' --> -- 'You might want to $1 a documentation page for this [[Wikipedia:Lua|Scribunto module]].' --]=] local docTitle = env.docTitle if not docTitle then return nil end local ret if docTitle.exists then -- /doc exists; link to it. local docLink = makeWikilink(docTitle.prefixedText) local editDisplay = message('edit-link-display') local editLink = makeWikilink("Special:EditPage/" .. docTitle.prefixedText, editDisplay) local historyDisplay = message('history-link-display') local historyLink = makeWikilink("Special:PageHistory/" .. docTitle.prefixedText, historyDisplay) ret = message('transcluded-from-blurb', {docLink}) .. ' ' .. makeToolbar(editLink, historyLink) .. '<br />' elseif env.subjectSpace == 828 then -- /doc does not exist; ask to create it. local createUrl = docTitle:canonicalUrl{action = 'edit', preload = message('module-preload')} local createDisplay = message('create-link-display') local createLink = makeUrlLink(createUrl, createDisplay) ret = message('create-module-doc-blurb', {createLink}) .. '<br />' end return ret end function p.makeExperimentBlurb(args, env) --[[ -- Renders the text "Editors can experiment in this template's sandbox (edit | diff) and testcases (edit) pages." -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- -- Messages: -- 'sandbox-link-display' --> 'sandbox' -- 'sandbox-edit-link-display' --> 'edit' -- 'compare-link-display' --> 'diff' -- 'module-sandbox-preload' --> 'Template:Documentation/preload-module-sandbox' -- 'template-sandbox-preload' --> 'Template:Documentation/preload-sandbox' -- 'sandbox-create-link-display' --> 'create' -- 'mirror-edit-summary' --> 'Create sandbox version of $1' -- 'mirror-link-display' --> 'mirror' -- 'mirror-link-preload' --> 'Template:Documentation/mirror' -- 'sandbox-link-display' --> 'sandbox' -- 'testcases-link-display' --> 'testcases' -- 'testcases-edit-link-display'--> 'edit' -- 'template-sandbox-preload' --> 'Template:Documentation/preload-sandbox' -- 'testcases-create-link-display' --> 'create' -- 'testcases-link-display' --> 'testcases' -- 'testcases-edit-link-display' --> 'edit' -- 'module-testcases-preload' --> 'Template:Documentation/preload-module-testcases' -- 'template-testcases-preload' --> 'Template:Documentation/preload-testcases' -- 'experiment-blurb-module' --> 'Editors can experiment in this module's $1 and $2 pages.' -- 'experiment-blurb-template' --> 'Editors can experiment in this template's $1 and $2 pages.' --]] local subjectSpace = env.subjectSpace local templateTitle = env.templateTitle local sandboxTitle = env.sandboxTitle local testcasesTitle = env.testcasesTitle local templatePage = templateTitle.prefixedText if not subjectSpace or not templateTitle or not sandboxTitle or not testcasesTitle then return nil end -- Make links. local sandboxLinks, testcasesLinks if sandboxTitle.exists then local sandboxPage = sandboxTitle.prefixedText local sandboxDisplay = message('sandbox-link-display') local sandboxLink = makeWikilink(sandboxPage, sandboxDisplay) local sandboxEditDisplay = message('sandbox-edit-link-display') local sandboxEditLink = makeWikilink("Special:EditPage/" .. sandboxPage, sandboxEditDisplay) local compareUrl = env.compareUrl local compareLink if compareUrl then local compareDisplay = message('compare-link-display') compareLink = makeUrlLink(compareUrl, compareDisplay) end sandboxLinks = sandboxLink .. ' ' .. makeToolbar(sandboxEditLink, compareLink) else local sandboxPreload if subjectSpace == 828 then sandboxPreload = message('module-sandbox-preload') else sandboxPreload = message('template-sandbox-preload') end local sandboxCreateUrl = sandboxTitle:canonicalUrl{action = 'edit', preload = sandboxPreload} local sandboxCreateDisplay = message('sandbox-create-link-display') local sandboxCreateLink = makeUrlLink(sandboxCreateUrl, sandboxCreateDisplay) local mirrorSummary = message('mirror-edit-summary', {makeWikilink(templatePage)}) local mirrorPreload = message('mirror-link-preload') local mirrorUrl = sandboxTitle:canonicalUrl{action = 'edit', preload = mirrorPreload, summary = mirrorSummary} if subjectSpace == 828 then mirrorUrl = sandboxTitle:canonicalUrl{action = 'edit', preload = templateTitle.prefixedText, summary = mirrorSummary} end local mirrorDisplay = message('mirror-link-display') local mirrorLink = makeUrlLink(mirrorUrl, mirrorDisplay) sandboxLinks = message('sandbox-link-display') .. ' ' .. makeToolbar(sandboxCreateLink, mirrorLink) end if testcasesTitle.exists then local testcasesPage = testcasesTitle.prefixedText local testcasesDisplay = message('testcases-link-display') local testcasesLink = makeWikilink(testcasesPage, testcasesDisplay) local testcasesEditUrl = testcasesTitle:canonicalUrl{action = 'edit'} local testcasesEditDisplay = message('testcases-edit-link-display') local testcasesEditLink = makeWikilink("Special:EditPage/" .. testcasesPage, testcasesEditDisplay) -- for Modules, add testcases run link if exists if testcasesTitle.contentModel == "Scribunto" and testcasesTitle.talkPageTitle and testcasesTitle.talkPageTitle.exists then local testcasesRunLinkDisplay = message('testcases-run-link-display') local testcasesRunLink = makeWikilink(testcasesTitle.talkPageTitle.prefixedText, testcasesRunLinkDisplay) testcasesLinks = testcasesLink .. ' ' .. makeToolbar(testcasesEditLink, testcasesRunLink) else testcasesLinks = testcasesLink .. ' ' .. makeToolbar(testcasesEditLink) end else local testcasesPreload if subjectSpace == 828 then testcasesPreload = message('module-testcases-preload') else testcasesPreload = message('template-testcases-preload') end local testcasesCreateUrl = testcasesTitle:canonicalUrl{action = 'edit', preload = testcasesPreload} local testcasesCreateDisplay = message('testcases-create-link-display') local testcasesCreateLink = makeUrlLink(testcasesCreateUrl, testcasesCreateDisplay) testcasesLinks = message('testcases-link-display') .. ' ' .. makeToolbar(testcasesCreateLink) end local messageName if subjectSpace == 828 then messageName = 'experiment-blurb-module' else messageName = 'experiment-blurb-template' end return message(messageName, {sandboxLinks, testcasesLinks}) end function p.makeCategoriesBlurb(args, env) --[[ -- Generates the text "Please add categories to the /doc subpage." -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- Messages: -- 'doc-link-display' --> '/doc' -- 'add-categories-blurb' --> 'Please add categories to the $1 subpage.' --]] local docTitle = env.docTitle if not docTitle then return nil end local docPathLink = makeWikilink(docTitle.prefixedText, message('doc-link-display')) return message('add-categories-blurb', {docPathLink}) end function p.makeSubpagesBlurb(args, env) --[[ -- Generates the "Subpages of this template" link. -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- Messages: -- 'template-pagetype' --> 'template' -- 'module-pagetype' --> 'module' -- 'default-pagetype' --> 'page' -- 'subpages-link-display' --> 'Subpages of this $1' --]] local subjectSpace = env.subjectSpace local templateTitle = env.templateTitle if not subjectSpace or not templateTitle then return nil end local pagetype if subjectSpace == 10 then pagetype = message('template-pagetype') elseif subjectSpace == 828 then pagetype = message('module-pagetype') else pagetype = message('default-pagetype') end local subpagesLink = makeWikilink( 'Special:PrefixIndex/' .. templateTitle.prefixedText .. '/', message('subpages-link-display', {pagetype}) ) return message('subpages-blurb', {subpagesLink}) end ---------------------------------------------------------------------------- -- Tracking categories ---------------------------------------------------------------------------- function p.addTrackingCategories(env) --[[ -- Check if {{documentation}} is transcluded on a /doc or /testcases page. -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- Messages: -- 'display-strange-usage-category' --> true -- 'doc-subpage' --> 'doc' -- 'testcases-subpage' --> 'testcases' -- 'strange-usage-category' --> 'Wikipedia pages with strange ((documentation)) usage' -- -- /testcases pages in the module namespace are not categorised, as they may have -- {{documentation}} transcluded automatically. --]] local title = env.title local subjectSpace = env.subjectSpace if not title or not subjectSpace then return nil end local subpage = title.subpageText local ret = '' if message('display-strange-usage-category', nil, 'boolean') and ( subpage == message('doc-subpage') or subjectSpace ~= 828 and subpage == message('testcases-subpage') ) then ret = ret .. makeCategoryLink(message('strange-usage-category')) end return ret end return p 268dc89480af10873bfbca5439ae8e61b404f770 7 6 2023-10-05T08:17:38Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Documentation]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- This module implements {{documentation}}. -- Get required modules. local getArgs = require('Module:Arguments').getArgs -- Get the config table. local cfg = mw.loadData('Module:Documentation/config') local p = {} -- Often-used functions. local ugsub = mw.ustring.gsub local format = mw.ustring.format ---------------------------------------------------------------------------- -- Helper functions -- -- These are defined as local functions, but are made available in the p -- table for testing purposes. ---------------------------------------------------------------------------- local function message(cfgKey, valArray, expectType) --[[ -- Gets a message from the cfg table and formats it if appropriate. -- The function raises an error if the value from the cfg table is not -- of the type expectType. The default type for expectType is 'string'. -- If the table valArray is present, strings such as $1, $2 etc. in the -- message are substituted with values from the table keys [1], [2] etc. -- For example, if the message "foo-message" had the value 'Foo $2 bar $1.', -- message('foo-message', {'baz', 'qux'}) would return "Foo qux bar baz." --]] local msg = cfg[cfgKey] expectType = expectType or 'string' if type(msg) ~= expectType then error('message: type error in message cfg.' .. cfgKey .. ' (' .. expectType .. ' expected, got ' .. type(msg) .. ')', 2) end if not valArray then return msg end local function getMessageVal(match) match = tonumber(match) return valArray[match] or error('message: no value found for key $' .. match .. ' in message cfg.' .. cfgKey, 4) end return ugsub(msg, '$([1-9][0-9]*)', getMessageVal) end p.message = message local function makeWikilink(page, display) if display then return format('[[%s|%s]]', page, display) else return format('[[%s]]', page) end end p.makeWikilink = makeWikilink local function makeCategoryLink(cat, sort) local catns = mw.site.namespaces[14].name return makeWikilink(catns .. ':' .. cat, sort) end p.makeCategoryLink = makeCategoryLink local function makeUrlLink(url, display) return format('[%s %s]', url, display) end p.makeUrlLink = makeUrlLink local function makeToolbar(...) local ret = {} local lim = select('#', ...) if lim < 1 then return nil end for i = 1, lim do ret[#ret + 1] = select(i, ...) end -- 'documentation-toolbar' return format( '<span class="%s">(%s)</span>', message('toolbar-class'), table.concat(ret, ' &#124; ') ) end p.makeToolbar = makeToolbar ---------------------------------------------------------------------------- -- Argument processing ---------------------------------------------------------------------------- local function makeInvokeFunc(funcName) return function (frame) local args = getArgs(frame, { valueFunc = function (key, value) if type(value) == 'string' then value = value:match('^%s*(.-)%s*$') -- Remove whitespace. if key == 'heading' or value ~= '' then return value else return nil end else return value end end }) return p[funcName](args) end end ---------------------------------------------------------------------------- -- Entry points ---------------------------------------------------------------------------- function p.nonexistent(frame) if mw.title.getCurrentTitle().subpageText == 'testcases' then return frame:expandTemplate{title = 'module test cases notice'} else return p.main(frame) end end p.main = makeInvokeFunc('_main') function p._main(args) --[[ -- This function defines logic flow for the module. -- @args - table of arguments passed by the user --]] local env = p.getEnvironment(args) local root = mw.html.create() root :wikitext(p._getModuleWikitext(args, env)) :wikitext(p.protectionTemplate(env)) :wikitext(p.sandboxNotice(args, env)) :tag('div') -- 'documentation-container' :addClass(message('container')) :attr('role', 'complementary') :attr('aria-labelledby', args.heading ~= '' and 'documentation-heading' or nil) :attr('aria-label', args.heading == '' and 'Documentation' or nil) :newline() :tag('div') -- 'documentation' :addClass(message('main-div-classes')) :newline() :wikitext(p._startBox(args, env)) :wikitext(p._content(args, env)) :tag('div') -- 'documentation-clear' :addClass(message('clear')) :done() :newline() :done() :wikitext(p._endBox(args, env)) :done() :wikitext(p.addTrackingCategories(env)) -- 'Module:Documentation/styles.css' return mw.getCurrentFrame():extensionTag ( 'templatestyles', '', {src=cfg['templatestyles'] }) .. tostring(root) end ---------------------------------------------------------------------------- -- Environment settings ---------------------------------------------------------------------------- function p.getEnvironment(args) --[[ -- Returns a table with information about the environment, including title -- objects and other namespace- or path-related data. -- @args - table of arguments passed by the user -- -- Title objects include: -- env.title - the page we are making documentation for (usually the current title) -- env.templateTitle - the template (or module, file, etc.) -- env.docTitle - the /doc subpage. -- env.sandboxTitle - the /sandbox subpage. -- env.testcasesTitle - the /testcases subpage. -- -- Data includes: -- env.protectionLevels - the protection levels table of the title object. -- env.subjectSpace - the number of the title's subject namespace. -- env.docSpace - the number of the namespace the title puts its documentation in. -- env.docpageBase - the text of the base page of the /doc, /sandbox and /testcases pages, with namespace. -- env.compareUrl - URL of the Special:ComparePages page comparing the sandbox with the template. -- -- All table lookups are passed through pcall so that errors are caught. If an error occurs, the value -- returned will be nil. --]] local env, envFuncs = {}, {} -- Set up the metatable. If triggered we call the corresponding function in the envFuncs table. The value -- returned by that function is memoized in the env table so that we don't call any of the functions -- more than once. (Nils won't be memoized.) setmetatable(env, { __index = function (t, key) local envFunc = envFuncs[key] if envFunc then local success, val = pcall(envFunc) if success then env[key] = val -- Memoise the value. return val end end return nil end }) function envFuncs.title() -- The title object for the current page, or a test page passed with args.page. local title local titleArg = args.page if titleArg then title = mw.title.new(titleArg) else title = mw.title.getCurrentTitle() end return title end function envFuncs.templateTitle() --[[ -- The template (or module, etc.) title object. -- Messages: -- 'sandbox-subpage' --> 'sandbox' -- 'testcases-subpage' --> 'testcases' --]] local subjectSpace = env.subjectSpace local title = env.title local subpage = title.subpageText if subpage == message('sandbox-subpage') or subpage == message('testcases-subpage') then return mw.title.makeTitle(subjectSpace, title.baseText) else return mw.title.makeTitle(subjectSpace, title.text) end end function envFuncs.docTitle() --[[ -- Title object of the /doc subpage. -- Messages: -- 'doc-subpage' --> 'doc' --]] local title = env.title local docname = args[1] -- User-specified doc page. local docpage if docname then docpage = docname else docpage = env.docpageBase .. '/' .. message('doc-subpage') end return mw.title.new(docpage) end function envFuncs.sandboxTitle() --[[ -- Title object for the /sandbox subpage. -- Messages: -- 'sandbox-subpage' --> 'sandbox' --]] return mw.title.new(env.docpageBase .. '/' .. message('sandbox-subpage')) end function envFuncs.testcasesTitle() --[[ -- Title object for the /testcases subpage. -- Messages: -- 'testcases-subpage' --> 'testcases' --]] return mw.title.new(env.docpageBase .. '/' .. message('testcases-subpage')) end function envFuncs.protectionLevels() -- The protection levels table of the title object. return env.title.protectionLevels end function envFuncs.subjectSpace() -- The subject namespace number. return mw.site.namespaces[env.title.namespace].subject.id end function envFuncs.docSpace() -- The documentation namespace number. For most namespaces this is the -- same as the subject namespace. However, pages in the Article, File, -- MediaWiki or Category namespaces must have their /doc, /sandbox and -- /testcases pages in talk space. local subjectSpace = env.subjectSpace if subjectSpace == 0 or subjectSpace == 6 or subjectSpace == 8 or subjectSpace == 14 then return subjectSpace + 1 else return subjectSpace end end function envFuncs.docpageBase() -- The base page of the /doc, /sandbox, and /testcases subpages. -- For some namespaces this is the talk page, rather than the template page. local templateTitle = env.templateTitle local docSpace = env.docSpace local docSpaceText = mw.site.namespaces[docSpace].name -- Assemble the link. docSpace is never the main namespace, so we can hardcode the colon. return docSpaceText .. ':' .. templateTitle.text end function envFuncs.compareUrl() -- Diff link between the sandbox and the main template using [[Special:ComparePages]]. local templateTitle = env.templateTitle local sandboxTitle = env.sandboxTitle if templateTitle.exists and sandboxTitle.exists then local compareUrl = mw.uri.canonicalUrl( 'Special:ComparePages', { page1 = templateTitle.prefixedText, page2 = sandboxTitle.prefixedText} ) return tostring(compareUrl) else return nil end end return env end ---------------------------------------------------------------------------- -- Auxiliary templates ---------------------------------------------------------------------------- p.getModuleWikitext = makeInvokeFunc('_getModuleWikitext') function p._getModuleWikitext(args, env) local currentTitle = mw.title.getCurrentTitle() if currentTitle.contentModel ~= 'Scribunto' then return end pcall(require, currentTitle.prefixedText) -- if it fails, we don't care local moduleWikitext = package.loaded["Module:Module wikitext"] if moduleWikitext then return moduleWikitext.main() end end function p.sandboxNotice(args, env) --[=[ -- Generates a sandbox notice for display above sandbox pages. -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- -- Messages: -- 'sandbox-notice-image' --> '[[File:Sandbox.svg|50px|alt=|link=]]' -- 'sandbox-notice-blurb' --> 'This is the $1 for $2.' -- 'sandbox-notice-diff-blurb' --> 'This is the $1 for $2 ($3).' -- 'sandbox-notice-pagetype-template' --> '[[Wikipedia:Template test cases|template sandbox]] page' -- 'sandbox-notice-pagetype-module' --> '[[Wikipedia:Template test cases|module sandbox]] page' -- 'sandbox-notice-pagetype-other' --> 'sandbox page' -- 'sandbox-notice-compare-link-display' --> 'diff' -- 'sandbox-notice-testcases-blurb' --> 'See also the companion subpage for $1.' -- 'sandbox-notice-testcases-link-display' --> 'test cases' -- 'sandbox-category' --> 'Template sandboxes' --]=] local title = env.title local sandboxTitle = env.sandboxTitle local templateTitle = env.templateTitle local subjectSpace = env.subjectSpace if not (subjectSpace and title and sandboxTitle and templateTitle and mw.title.equals(title, sandboxTitle)) then return nil end -- Build the table of arguments to pass to {{ombox}}. We need just two fields, "image" and "text". local omargs = {} omargs.image = message('sandbox-notice-image') -- Get the text. We start with the opening blurb, which is something like -- "This is the template sandbox for [[Template:Foo]] (diff)." local text = '' local pagetype if subjectSpace == 10 then pagetype = message('sandbox-notice-pagetype-template') elseif subjectSpace == 828 then pagetype = message('sandbox-notice-pagetype-module') else pagetype = message('sandbox-notice-pagetype-other') end local templateLink = makeWikilink(templateTitle.prefixedText) local compareUrl = env.compareUrl if compareUrl then local compareDisplay = message('sandbox-notice-compare-link-display') local compareLink = makeUrlLink(compareUrl, compareDisplay) text = text .. message('sandbox-notice-diff-blurb', {pagetype, templateLink, compareLink}) else text = text .. message('sandbox-notice-blurb', {pagetype, templateLink}) end -- Get the test cases page blurb if the page exists. This is something like -- "See also the companion subpage for [[Template:Foo/testcases|test cases]]." local testcasesTitle = env.testcasesTitle if testcasesTitle and testcasesTitle.exists then if testcasesTitle.contentModel == "Scribunto" then local testcasesLinkDisplay = message('sandbox-notice-testcases-link-display') local testcasesRunLinkDisplay = message('sandbox-notice-testcases-run-link-display') local testcasesLink = makeWikilink(testcasesTitle.prefixedText, testcasesLinkDisplay) local testcasesRunLink = makeWikilink(testcasesTitle.talkPageTitle.prefixedText, testcasesRunLinkDisplay) text = text .. '<br />' .. message('sandbox-notice-testcases-run-blurb', {testcasesLink, testcasesRunLink}) else local testcasesLinkDisplay = message('sandbox-notice-testcases-link-display') local testcasesLink = makeWikilink(testcasesTitle.prefixedText, testcasesLinkDisplay) text = text .. '<br />' .. message('sandbox-notice-testcases-blurb', {testcasesLink}) end end -- Add the sandbox to the sandbox category. omargs.text = text .. makeCategoryLink(message('sandbox-category')) -- 'documentation-clear' return '<div class="' .. message('clear') .. '"></div>' .. require('Module:Message box').main('ombox', omargs) end function p.protectionTemplate(env) -- Generates the padlock icon in the top right. -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- Messages: -- 'protection-template' --> 'pp-template' -- 'protection-template-args' --> {docusage = 'yes'} local protectionLevels = env.protectionLevels if not protectionLevels then return nil end local editProt = protectionLevels.edit and protectionLevels.edit[1] local moveProt = protectionLevels.move and protectionLevels.move[1] if editProt then -- The page is edit-protected. return require('Module:Protection banner')._main{ message('protection-reason-edit'), small = true } elseif moveProt and moveProt ~= 'autoconfirmed' then -- The page is move-protected but not edit-protected. Exclude move -- protection with the level "autoconfirmed", as this is equivalent to -- no move protection at all. return require('Module:Protection banner')._main{ action = 'move', small = true } else return nil end end ---------------------------------------------------------------------------- -- Start box ---------------------------------------------------------------------------- p.startBox = makeInvokeFunc('_startBox') function p._startBox(args, env) --[[ -- This function generates the start box. -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- -- The actual work is done by p.makeStartBoxLinksData and p.renderStartBoxLinks which make -- the [view] [edit] [history] [purge] links, and by p.makeStartBoxData and p.renderStartBox -- which generate the box HTML. --]] env = env or p.getEnvironment(args) local links local content = args.content if not content or args[1] then -- No need to include the links if the documentation is on the template page itself. local linksData = p.makeStartBoxLinksData(args, env) if linksData then links = p.renderStartBoxLinks(linksData) end end -- Generate the start box html. local data = p.makeStartBoxData(args, env, links) if data then return p.renderStartBox(data) else -- User specified no heading. return nil end end function p.makeStartBoxLinksData(args, env) --[[ -- Does initial processing of data to make the [view] [edit] [history] [purge] links. -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- -- Messages: -- 'view-link-display' --> 'view' -- 'edit-link-display' --> 'edit' -- 'history-link-display' --> 'history' -- 'purge-link-display' --> 'purge' -- 'module-preload' --> 'Template:Documentation/preload-module-doc' -- 'docpage-preload' --> 'Template:Documentation/preload' -- 'create-link-display' --> 'create' --]] local subjectSpace = env.subjectSpace local title = env.title local docTitle = env.docTitle if not title or not docTitle then return nil end if docTitle.isRedirect then docTitle = docTitle.redirectTarget end -- Create link if /doc doesn't exist. local preload = args.preload if not preload then if subjectSpace == 828 then -- Module namespace preload = message('module-preload') else preload = message('docpage-preload') end end return { title = title, docTitle = docTitle, -- View, display, edit, and purge links if /doc exists. viewLinkDisplay = message('view-link-display'), editLinkDisplay = message('edit-link-display'), historyLinkDisplay = message('history-link-display'), purgeLinkDisplay = message('purge-link-display'), preload = preload, createLinkDisplay = message('create-link-display') } end function p.renderStartBoxLinks(data) --[[ -- Generates the [view][edit][history][purge] or [create][purge] links from the data table. -- @data - a table of data generated by p.makeStartBoxLinksData --]] local docTitle = data.docTitle -- yes, we do intend to purge the template page on which the documentation appears local purgeLink = makeWikilink("Special:Purge/" .. data.title.prefixedText, data.purgeLinkDisplay) if docTitle.exists then local viewLink = makeWikilink(docTitle.prefixedText, data.viewLinkDisplay) local editLink = makeWikilink("Special:EditPage/" .. docTitle.prefixedText, data.editLinkDisplay) local historyLink = makeWikilink("Special:PageHistory/" .. docTitle.prefixedText, data.historyLinkDisplay) return "&#91;" .. viewLink .. "&#93; &#91;" .. editLink .. "&#93; &#91;" .. historyLink .. "&#93; &#91;" .. purgeLink .. "&#93;" else local createLink = makeUrlLink(docTitle:canonicalUrl{action = 'edit', preload = data.preload}, data.createLinkDisplay) return "&#91;" .. createLink .. "&#93; &#91;" .. purgeLink .. "&#93;" end return ret end function p.makeStartBoxData(args, env, links) --[=[ -- Does initial processing of data to pass to the start-box render function, p.renderStartBox. -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- @links - a string containing the [view][edit][history][purge] links - could be nil if there's an error. -- -- Messages: -- 'documentation-icon-wikitext' --> '[[File:Test Template Info-Icon - Version (2).svg|50px|link=|alt=]]' -- 'template-namespace-heading' --> 'Template documentation' -- 'module-namespace-heading' --> 'Module documentation' -- 'file-namespace-heading' --> 'Summary' -- 'other-namespaces-heading' --> 'Documentation' -- 'testcases-create-link-display' --> 'create' --]=] local subjectSpace = env.subjectSpace if not subjectSpace then -- Default to an "other namespaces" namespace, so that we get at least some output -- if an error occurs. subjectSpace = 2 end local data = {} -- Heading local heading = args.heading -- Blank values are not removed. if heading == '' then -- Don't display the start box if the heading arg is defined but blank. return nil end if heading then data.heading = heading elseif subjectSpace == 10 then -- Template namespace data.heading = message('documentation-icon-wikitext') .. ' ' .. message('template-namespace-heading') elseif subjectSpace == 828 then -- Module namespace data.heading = message('documentation-icon-wikitext') .. ' ' .. message('module-namespace-heading') elseif subjectSpace == 6 then -- File namespace data.heading = message('file-namespace-heading') else data.heading = message('other-namespaces-heading') end -- Heading CSS local headingStyle = args['heading-style'] if headingStyle then data.headingStyleText = headingStyle else -- 'documentation-heading' data.headingClass = message('main-div-heading-class') end -- Data for the [view][edit][history][purge] or [create] links. if links then -- 'mw-editsection-like plainlinks' data.linksClass = message('start-box-link-classes') data.links = links end return data end function p.renderStartBox(data) -- Renders the start box html. -- @data - a table of data generated by p.makeStartBoxData. local sbox = mw.html.create('div') sbox -- 'documentation-startbox' :addClass(message('start-box-class')) :newline() :tag('span') :addClass(data.headingClass) :attr('id', 'documentation-heading') :cssText(data.headingStyleText) :wikitext(data.heading) local links = data.links if links then sbox:tag('span') :addClass(data.linksClass) :attr('id', data.linksId) :wikitext(links) end return tostring(sbox) end ---------------------------------------------------------------------------- -- Documentation content ---------------------------------------------------------------------------- p.content = makeInvokeFunc('_content') function p._content(args, env) -- Displays the documentation contents -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment env = env or p.getEnvironment(args) local docTitle = env.docTitle local content = args.content if not content and docTitle and docTitle.exists then content = args._content or mw.getCurrentFrame():expandTemplate{title = docTitle.prefixedText} end -- The line breaks below are necessary so that "=== Headings ===" at the start and end -- of docs are interpreted correctly. return '\n' .. (content or '') .. '\n' end p.contentTitle = makeInvokeFunc('_contentTitle') function p._contentTitle(args, env) env = env or p.getEnvironment(args) local docTitle = env.docTitle if not args.content and docTitle and docTitle.exists then return docTitle.prefixedText else return '' end end ---------------------------------------------------------------------------- -- End box ---------------------------------------------------------------------------- p.endBox = makeInvokeFunc('_endBox') function p._endBox(args, env) --[=[ -- This function generates the end box (also known as the link box). -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- --]=] -- Get environment data. env = env or p.getEnvironment(args) local subjectSpace = env.subjectSpace local docTitle = env.docTitle if not subjectSpace or not docTitle then return nil end -- Check whether we should output the end box at all. Add the end -- box by default if the documentation exists or if we are in the -- user, module or template namespaces. local linkBox = args['link box'] if linkBox == 'off' or not ( docTitle.exists or subjectSpace == 2 or subjectSpace == 828 or subjectSpace == 10 ) then return nil end -- Assemble the link box. local text = '' if linkBox then text = text .. linkBox else text = text .. (p.makeDocPageBlurb(args, env) or '') -- "This documentation is transcluded from [[Foo]]." if subjectSpace == 2 or subjectSpace == 10 or subjectSpace == 828 then -- We are in the user, template or module namespaces. -- Add sandbox and testcases links. -- "Editors can experiment in this template's sandbox and testcases pages." text = text .. (p.makeExperimentBlurb(args, env) or '') .. '<br />' if not args.content and not args[1] then -- "Please add categories to the /doc subpage." -- Don't show this message with inline docs or with an explicitly specified doc page, -- as then it is unclear where to add the categories. text = text .. (p.makeCategoriesBlurb(args, env) or '') end text = text .. ' ' .. (p.makeSubpagesBlurb(args, env) or '') --"Subpages of this template" end end local box = mw.html.create('div') -- 'documentation-metadata' box:attr('role', 'note') :addClass(message('end-box-class')) -- 'plainlinks' :addClass(message('end-box-plainlinks')) :wikitext(text) :done() return '\n' .. tostring(box) end function p.makeDocPageBlurb(args, env) --[=[ -- Makes the blurb "This documentation is transcluded from [[Template:Foo]] (edit, history)". -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- -- Messages: -- 'edit-link-display' --> 'edit' -- 'history-link-display' --> 'history' -- 'transcluded-from-blurb' --> -- 'The above [[Wikipedia:Template documentation|documentation]] -- is [[Help:Transclusion|transcluded]] from $1.' -- 'module-preload' --> 'Template:Documentation/preload-module-doc' -- 'create-link-display' --> 'create' -- 'create-module-doc-blurb' --> -- 'You might want to $1 a documentation page for this [[Wikipedia:Lua|Scribunto module]].' --]=] local docTitle = env.docTitle if not docTitle then return nil end local ret if docTitle.exists then -- /doc exists; link to it. local docLink = makeWikilink(docTitle.prefixedText) local editDisplay = message('edit-link-display') local editLink = makeWikilink("Special:EditPage/" .. docTitle.prefixedText, editDisplay) local historyDisplay = message('history-link-display') local historyLink = makeWikilink("Special:PageHistory/" .. docTitle.prefixedText, historyDisplay) ret = message('transcluded-from-blurb', {docLink}) .. ' ' .. makeToolbar(editLink, historyLink) .. '<br />' elseif env.subjectSpace == 828 then -- /doc does not exist; ask to create it. local createUrl = docTitle:canonicalUrl{action = 'edit', preload = message('module-preload')} local createDisplay = message('create-link-display') local createLink = makeUrlLink(createUrl, createDisplay) ret = message('create-module-doc-blurb', {createLink}) .. '<br />' end return ret end function p.makeExperimentBlurb(args, env) --[[ -- Renders the text "Editors can experiment in this template's sandbox (edit | diff) and testcases (edit) pages." -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- -- Messages: -- 'sandbox-link-display' --> 'sandbox' -- 'sandbox-edit-link-display' --> 'edit' -- 'compare-link-display' --> 'diff' -- 'module-sandbox-preload' --> 'Template:Documentation/preload-module-sandbox' -- 'template-sandbox-preload' --> 'Template:Documentation/preload-sandbox' -- 'sandbox-create-link-display' --> 'create' -- 'mirror-edit-summary' --> 'Create sandbox version of $1' -- 'mirror-link-display' --> 'mirror' -- 'mirror-link-preload' --> 'Template:Documentation/mirror' -- 'sandbox-link-display' --> 'sandbox' -- 'testcases-link-display' --> 'testcases' -- 'testcases-edit-link-display'--> 'edit' -- 'template-sandbox-preload' --> 'Template:Documentation/preload-sandbox' -- 'testcases-create-link-display' --> 'create' -- 'testcases-link-display' --> 'testcases' -- 'testcases-edit-link-display' --> 'edit' -- 'module-testcases-preload' --> 'Template:Documentation/preload-module-testcases' -- 'template-testcases-preload' --> 'Template:Documentation/preload-testcases' -- 'experiment-blurb-module' --> 'Editors can experiment in this module's $1 and $2 pages.' -- 'experiment-blurb-template' --> 'Editors can experiment in this template's $1 and $2 pages.' --]] local subjectSpace = env.subjectSpace local templateTitle = env.templateTitle local sandboxTitle = env.sandboxTitle local testcasesTitle = env.testcasesTitle local templatePage = templateTitle.prefixedText if not subjectSpace or not templateTitle or not sandboxTitle or not testcasesTitle then return nil end -- Make links. local sandboxLinks, testcasesLinks if sandboxTitle.exists then local sandboxPage = sandboxTitle.prefixedText local sandboxDisplay = message('sandbox-link-display') local sandboxLink = makeWikilink(sandboxPage, sandboxDisplay) local sandboxEditDisplay = message('sandbox-edit-link-display') local sandboxEditLink = makeWikilink("Special:EditPage/" .. sandboxPage, sandboxEditDisplay) local compareUrl = env.compareUrl local compareLink if compareUrl then local compareDisplay = message('compare-link-display') compareLink = makeUrlLink(compareUrl, compareDisplay) end sandboxLinks = sandboxLink .. ' ' .. makeToolbar(sandboxEditLink, compareLink) else local sandboxPreload if subjectSpace == 828 then sandboxPreload = message('module-sandbox-preload') else sandboxPreload = message('template-sandbox-preload') end local sandboxCreateUrl = sandboxTitle:canonicalUrl{action = 'edit', preload = sandboxPreload} local sandboxCreateDisplay = message('sandbox-create-link-display') local sandboxCreateLink = makeUrlLink(sandboxCreateUrl, sandboxCreateDisplay) local mirrorSummary = message('mirror-edit-summary', {makeWikilink(templatePage)}) local mirrorPreload = message('mirror-link-preload') local mirrorUrl = sandboxTitle:canonicalUrl{action = 'edit', preload = mirrorPreload, summary = mirrorSummary} if subjectSpace == 828 then mirrorUrl = sandboxTitle:canonicalUrl{action = 'edit', preload = templateTitle.prefixedText, summary = mirrorSummary} end local mirrorDisplay = message('mirror-link-display') local mirrorLink = makeUrlLink(mirrorUrl, mirrorDisplay) sandboxLinks = message('sandbox-link-display') .. ' ' .. makeToolbar(sandboxCreateLink, mirrorLink) end if testcasesTitle.exists then local testcasesPage = testcasesTitle.prefixedText local testcasesDisplay = message('testcases-link-display') local testcasesLink = makeWikilink(testcasesPage, testcasesDisplay) local testcasesEditUrl = testcasesTitle:canonicalUrl{action = 'edit'} local testcasesEditDisplay = message('testcases-edit-link-display') local testcasesEditLink = makeWikilink("Special:EditPage/" .. testcasesPage, testcasesEditDisplay) -- for Modules, add testcases run link if exists if testcasesTitle.contentModel == "Scribunto" and testcasesTitle.talkPageTitle and testcasesTitle.talkPageTitle.exists then local testcasesRunLinkDisplay = message('testcases-run-link-display') local testcasesRunLink = makeWikilink(testcasesTitle.talkPageTitle.prefixedText, testcasesRunLinkDisplay) testcasesLinks = testcasesLink .. ' ' .. makeToolbar(testcasesEditLink, testcasesRunLink) else testcasesLinks = testcasesLink .. ' ' .. makeToolbar(testcasesEditLink) end else local testcasesPreload if subjectSpace == 828 then testcasesPreload = message('module-testcases-preload') else testcasesPreload = message('template-testcases-preload') end local testcasesCreateUrl = testcasesTitle:canonicalUrl{action = 'edit', preload = testcasesPreload} local testcasesCreateDisplay = message('testcases-create-link-display') local testcasesCreateLink = makeUrlLink(testcasesCreateUrl, testcasesCreateDisplay) testcasesLinks = message('testcases-link-display') .. ' ' .. makeToolbar(testcasesCreateLink) end local messageName if subjectSpace == 828 then messageName = 'experiment-blurb-module' else messageName = 'experiment-blurb-template' end return message(messageName, {sandboxLinks, testcasesLinks}) end function p.makeCategoriesBlurb(args, env) --[[ -- Generates the text "Please add categories to the /doc subpage." -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- Messages: -- 'doc-link-display' --> '/doc' -- 'add-categories-blurb' --> 'Please add categories to the $1 subpage.' --]] local docTitle = env.docTitle if not docTitle then return nil end local docPathLink = makeWikilink(docTitle.prefixedText, message('doc-link-display')) return message('add-categories-blurb', {docPathLink}) end function p.makeSubpagesBlurb(args, env) --[[ -- Generates the "Subpages of this template" link. -- @args - a table of arguments passed by the user -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- Messages: -- 'template-pagetype' --> 'template' -- 'module-pagetype' --> 'module' -- 'default-pagetype' --> 'page' -- 'subpages-link-display' --> 'Subpages of this $1' --]] local subjectSpace = env.subjectSpace local templateTitle = env.templateTitle if not subjectSpace or not templateTitle then return nil end local pagetype if subjectSpace == 10 then pagetype = message('template-pagetype') elseif subjectSpace == 828 then pagetype = message('module-pagetype') else pagetype = message('default-pagetype') end local subpagesLink = makeWikilink( 'Special:PrefixIndex/' .. templateTitle.prefixedText .. '/', message('subpages-link-display', {pagetype}) ) return message('subpages-blurb', {subpagesLink}) end ---------------------------------------------------------------------------- -- Tracking categories ---------------------------------------------------------------------------- function p.addTrackingCategories(env) --[[ -- Check if {{documentation}} is transcluded on a /doc or /testcases page. -- @env - environment table containing title objects, etc., generated with p.getEnvironment -- Messages: -- 'display-strange-usage-category' --> true -- 'doc-subpage' --> 'doc' -- 'testcases-subpage' --> 'testcases' -- 'strange-usage-category' --> 'Wikipedia pages with strange ((documentation)) usage' -- -- /testcases pages in the module namespace are not categorised, as they may have -- {{documentation}} transcluded automatically. --]] local title = env.title local subjectSpace = env.subjectSpace if not title or not subjectSpace then return nil end local subpage = title.subpageText local ret = '' if message('display-strange-usage-category', nil, 'boolean') and ( subpage == message('doc-subpage') or subjectSpace ~= 828 and subpage == message('testcases-subpage') ) then ret = ret .. makeCategoryLink(message('strange-usage-category')) end return ret end return p 268dc89480af10873bfbca5439ae8e61b404f770 มอดูล:Arguments 828 7 8 2023-10-05T08:20:30Z PeachFullzZ 2 สร้างหน้าด้วย "-- This module provides easy processing of arguments passed to Scribunto from -- #invoke. It is intended for use by other Lua modules, and should not be -- called from #invoke directly. local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local arguments = {} -- Generate four different tidyVal functions, so that we don't have to check the -- options every time we call it. local function tidyValDefault(key, val) if..." Scribunto text/plain -- This module provides easy processing of arguments passed to Scribunto from -- #invoke. It is intended for use by other Lua modules, and should not be -- called from #invoke directly. local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local arguments = {} -- Generate four different tidyVal functions, so that we don't have to check the -- options every time we call it. local function tidyValDefault(key, val) if type(val) == 'string' then val = val:match('^%s*(.-)%s*$') if val == '' then return nil else return val end else return val end end local function tidyValTrimOnly(key, val) if type(val) == 'string' then return val:match('^%s*(.-)%s*$') else return val end end local function tidyValRemoveBlanksOnly(key, val) if type(val) == 'string' then if val:find('%S') then return val else return nil end else return val end end local function tidyValNoChange(key, val) return val end local function matchesTitle(given, title) local tp = type( given ) return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title end local translate_mt = { __index = function(t, k) return k end } function arguments.getArgs(frame, options) checkType('getArgs', 1, frame, 'table', true) checkType('getArgs', 2, options, 'table', true) frame = frame or {} options = options or {} --[[ -- Set up argument translation. --]] options.translate = options.translate or {} if getmetatable(options.translate) == nil then setmetatable(options.translate, translate_mt) end if options.backtranslate == nil then options.backtranslate = {} for k,v in pairs(options.translate) do options.backtranslate[v] = k end end if options.backtranslate and getmetatable(options.backtranslate) == nil then setmetatable(options.backtranslate, { __index = function(t, k) if options.translate[k] ~= k then return nil else return k end end }) end --[[ -- Get the argument tables. If we were passed a valid frame object, get the -- frame arguments (fargs) and the parent frame arguments (pargs), depending -- on the options set and on the parent frame's availability. If we weren't -- passed a valid frame object, we are being called from another Lua module -- or from the debug console, so assume that we were passed a table of args -- directly, and assign it to a new variable (luaArgs). --]] local fargs, pargs, luaArgs if type(frame.args) == 'table' and type(frame.getParent) == 'function' then if options.wrappers then --[[ -- The wrappers option makes Module:Arguments look up arguments in -- either the frame argument table or the parent argument table, but -- not both. This means that users can use either the #invoke syntax -- or a wrapper template without the loss of performance associated -- with looking arguments up in both the frame and the parent frame. -- Module:Arguments will look up arguments in the parent frame -- if it finds the parent frame's title in options.wrapper; -- otherwise it will look up arguments in the frame object passed -- to getArgs. --]] local parent = frame:getParent() if not parent then fargs = frame.args else local title = parent:getTitle():gsub('/sandbox$', '') local found = false if matchesTitle(options.wrappers, title) then found = true elseif type(options.wrappers) == 'table' then for _,v in pairs(options.wrappers) do if matchesTitle(v, title) then found = true break end end end -- We test for false specifically here so that nil (the default) acts like true. if found or options.frameOnly == false then pargs = parent.args end if not found or options.parentOnly == false then fargs = frame.args end end else -- options.wrapper isn't set, so check the other options. if not options.parentOnly then fargs = frame.args end if not options.frameOnly then local parent = frame:getParent() pargs = parent and parent.args or nil end end if options.parentFirst then fargs, pargs = pargs, fargs end else luaArgs = frame end -- Set the order of precedence of the argument tables. If the variables are -- nil, nothing will be added to the table, which is how we avoid clashes -- between the frame/parent args and the Lua args. local argTables = {fargs} argTables[#argTables + 1] = pargs argTables[#argTables + 1] = luaArgs --[[ -- Generate the tidyVal function. If it has been specified by the user, we -- use that; if not, we choose one of four functions depending on the -- options chosen. This is so that we don't have to call the options table -- every time the function is called. --]] local tidyVal = options.valueFunc if tidyVal then if type(tidyVal) ~= 'function' then error( "bad value assigned to option 'valueFunc'" .. '(function expected, got ' .. type(tidyVal) .. ')', 2 ) end elseif options.trim ~= false then if options.removeBlanks ~= false then tidyVal = tidyValDefault else tidyVal = tidyValTrimOnly end else if options.removeBlanks ~= false then tidyVal = tidyValRemoveBlanksOnly else tidyVal = tidyValNoChange end end --[[ -- Set up the args, metaArgs and nilArgs tables. args will be the one -- accessed from functions, and metaArgs will hold the actual arguments. Nil -- arguments are memoized in nilArgs, and the metatable connects all of them -- together. --]] local args, metaArgs, nilArgs, metatable = {}, {}, {}, {} setmetatable(args, metatable) local function mergeArgs(tables) --[[ -- Accepts multiple tables as input and merges their keys and values -- into one table. If a value is already present it is not overwritten; -- tables listed earlier have precedence. We are also memoizing nil -- values, which can be overwritten if they are 's' (soft). --]] for _, t in ipairs(tables) do for key, val in pairs(t) do if metaArgs[key] == nil and nilArgs[key] ~= 'h' then local tidiedVal = tidyVal(key, val) if tidiedVal == nil then nilArgs[key] = 's' else metaArgs[key] = tidiedVal end end end end end --[[ -- Define metatable behaviour. Arguments are memoized in the metaArgs table, -- and are only fetched from the argument tables once. Fetching arguments -- from the argument tables is the most resource-intensive step in this -- module, so we try and avoid it where possible. For this reason, nil -- arguments are also memoized, in the nilArgs table. Also, we keep a record -- in the metatable of when pairs and ipairs have been called, so we do not -- run pairs and ipairs on the argument tables more than once. We also do -- not run ipairs on fargs and pargs if pairs has already been run, as all -- the arguments will already have been copied over. --]] metatable.__index = function (t, key) --[[ -- Fetches an argument when the args table is indexed. First we check -- to see if the value is memoized, and if not we try and fetch it from -- the argument tables. When we check memoization, we need to check -- metaArgs before nilArgs, as both can be non-nil at the same time. -- If the argument is not present in metaArgs, we also check whether -- pairs has been run yet. If pairs has already been run, we return nil. -- This is because all the arguments will have already been copied into -- metaArgs by the mergeArgs function, meaning that any other arguments -- must be nil. --]] if type(key) == 'string' then key = options.translate[key] end local val = metaArgs[key] if val ~= nil then return val elseif metatable.donePairs or nilArgs[key] then return nil end for _, argTable in ipairs(argTables) do local argTableVal = tidyVal(key, argTable[key]) if argTableVal ~= nil then metaArgs[key] = argTableVal return argTableVal end end nilArgs[key] = 'h' return nil end metatable.__newindex = function (t, key, val) -- This function is called when a module tries to add a new value to the -- args table, or tries to change an existing value. if type(key) == 'string' then key = options.translate[key] end if options.readOnly then error( 'could not write to argument table key "' .. tostring(key) .. '"; the table is read-only', 2 ) elseif options.noOverwrite and args[key] ~= nil then error( 'could not write to argument table key "' .. tostring(key) .. '"; overwriting existing arguments is not permitted', 2 ) elseif val == nil then --[[ -- If the argument is to be overwritten with nil, we need to erase -- the value in metaArgs, so that __index, __pairs and __ipairs do -- not use a previous existing value, if present; and we also need -- to memoize the nil in nilArgs, so that the value isn't looked -- up in the argument tables if it is accessed again. --]] metaArgs[key] = nil nilArgs[key] = 'h' else metaArgs[key] = val end end local function translatenext(invariant) local k, v = next(invariant.t, invariant.k) invariant.k = k if k == nil then return nil elseif type(k) ~= 'string' or not options.backtranslate then return k, v else local backtranslate = options.backtranslate[k] if backtranslate == nil then -- Skip this one. This is a tail call, so this won't cause stack overflow return translatenext(invariant) else return backtranslate, v end end end metatable.__pairs = function () -- Called when pairs is run on the args table. if not metatable.donePairs then mergeArgs(argTables) metatable.donePairs = true end return translatenext, { t = metaArgs } end local function inext(t, i) -- This uses our __index metamethod local v = t[i + 1] if v ~= nil then return i + 1, v end end metatable.__ipairs = function (t) -- Called when ipairs is run on the args table. return inext, t, 0 end return args end return arguments 3134ecce8429b810d445e29eae115e2ae4c36c53 9 8 2023-10-05T08:20:50Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Arguments]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- This module provides easy processing of arguments passed to Scribunto from -- #invoke. It is intended for use by other Lua modules, and should not be -- called from #invoke directly. local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local arguments = {} -- Generate four different tidyVal functions, so that we don't have to check the -- options every time we call it. local function tidyValDefault(key, val) if type(val) == 'string' then val = val:match('^%s*(.-)%s*$') if val == '' then return nil else return val end else return val end end local function tidyValTrimOnly(key, val) if type(val) == 'string' then return val:match('^%s*(.-)%s*$') else return val end end local function tidyValRemoveBlanksOnly(key, val) if type(val) == 'string' then if val:find('%S') then return val else return nil end else return val end end local function tidyValNoChange(key, val) return val end local function matchesTitle(given, title) local tp = type( given ) return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title end local translate_mt = { __index = function(t, k) return k end } function arguments.getArgs(frame, options) checkType('getArgs', 1, frame, 'table', true) checkType('getArgs', 2, options, 'table', true) frame = frame or {} options = options or {} --[[ -- Set up argument translation. --]] options.translate = options.translate or {} if getmetatable(options.translate) == nil then setmetatable(options.translate, translate_mt) end if options.backtranslate == nil then options.backtranslate = {} for k,v in pairs(options.translate) do options.backtranslate[v] = k end end if options.backtranslate and getmetatable(options.backtranslate) == nil then setmetatable(options.backtranslate, { __index = function(t, k) if options.translate[k] ~= k then return nil else return k end end }) end --[[ -- Get the argument tables. If we were passed a valid frame object, get the -- frame arguments (fargs) and the parent frame arguments (pargs), depending -- on the options set and on the parent frame's availability. If we weren't -- passed a valid frame object, we are being called from another Lua module -- or from the debug console, so assume that we were passed a table of args -- directly, and assign it to a new variable (luaArgs). --]] local fargs, pargs, luaArgs if type(frame.args) == 'table' and type(frame.getParent) == 'function' then if options.wrappers then --[[ -- The wrappers option makes Module:Arguments look up arguments in -- either the frame argument table or the parent argument table, but -- not both. This means that users can use either the #invoke syntax -- or a wrapper template without the loss of performance associated -- with looking arguments up in both the frame and the parent frame. -- Module:Arguments will look up arguments in the parent frame -- if it finds the parent frame's title in options.wrapper; -- otherwise it will look up arguments in the frame object passed -- to getArgs. --]] local parent = frame:getParent() if not parent then fargs = frame.args else local title = parent:getTitle():gsub('/sandbox$', '') local found = false if matchesTitle(options.wrappers, title) then found = true elseif type(options.wrappers) == 'table' then for _,v in pairs(options.wrappers) do if matchesTitle(v, title) then found = true break end end end -- We test for false specifically here so that nil (the default) acts like true. if found or options.frameOnly == false then pargs = parent.args end if not found or options.parentOnly == false then fargs = frame.args end end else -- options.wrapper isn't set, so check the other options. if not options.parentOnly then fargs = frame.args end if not options.frameOnly then local parent = frame:getParent() pargs = parent and parent.args or nil end end if options.parentFirst then fargs, pargs = pargs, fargs end else luaArgs = frame end -- Set the order of precedence of the argument tables. If the variables are -- nil, nothing will be added to the table, which is how we avoid clashes -- between the frame/parent args and the Lua args. local argTables = {fargs} argTables[#argTables + 1] = pargs argTables[#argTables + 1] = luaArgs --[[ -- Generate the tidyVal function. If it has been specified by the user, we -- use that; if not, we choose one of four functions depending on the -- options chosen. This is so that we don't have to call the options table -- every time the function is called. --]] local tidyVal = options.valueFunc if tidyVal then if type(tidyVal) ~= 'function' then error( "bad value assigned to option 'valueFunc'" .. '(function expected, got ' .. type(tidyVal) .. ')', 2 ) end elseif options.trim ~= false then if options.removeBlanks ~= false then tidyVal = tidyValDefault else tidyVal = tidyValTrimOnly end else if options.removeBlanks ~= false then tidyVal = tidyValRemoveBlanksOnly else tidyVal = tidyValNoChange end end --[[ -- Set up the args, metaArgs and nilArgs tables. args will be the one -- accessed from functions, and metaArgs will hold the actual arguments. Nil -- arguments are memoized in nilArgs, and the metatable connects all of them -- together. --]] local args, metaArgs, nilArgs, metatable = {}, {}, {}, {} setmetatable(args, metatable) local function mergeArgs(tables) --[[ -- Accepts multiple tables as input and merges their keys and values -- into one table. If a value is already present it is not overwritten; -- tables listed earlier have precedence. We are also memoizing nil -- values, which can be overwritten if they are 's' (soft). --]] for _, t in ipairs(tables) do for key, val in pairs(t) do if metaArgs[key] == nil and nilArgs[key] ~= 'h' then local tidiedVal = tidyVal(key, val) if tidiedVal == nil then nilArgs[key] = 's' else metaArgs[key] = tidiedVal end end end end end --[[ -- Define metatable behaviour. Arguments are memoized in the metaArgs table, -- and are only fetched from the argument tables once. Fetching arguments -- from the argument tables is the most resource-intensive step in this -- module, so we try and avoid it where possible. For this reason, nil -- arguments are also memoized, in the nilArgs table. Also, we keep a record -- in the metatable of when pairs and ipairs have been called, so we do not -- run pairs and ipairs on the argument tables more than once. We also do -- not run ipairs on fargs and pargs if pairs has already been run, as all -- the arguments will already have been copied over. --]] metatable.__index = function (t, key) --[[ -- Fetches an argument when the args table is indexed. First we check -- to see if the value is memoized, and if not we try and fetch it from -- the argument tables. When we check memoization, we need to check -- metaArgs before nilArgs, as both can be non-nil at the same time. -- If the argument is not present in metaArgs, we also check whether -- pairs has been run yet. If pairs has already been run, we return nil. -- This is because all the arguments will have already been copied into -- metaArgs by the mergeArgs function, meaning that any other arguments -- must be nil. --]] if type(key) == 'string' then key = options.translate[key] end local val = metaArgs[key] if val ~= nil then return val elseif metatable.donePairs or nilArgs[key] then return nil end for _, argTable in ipairs(argTables) do local argTableVal = tidyVal(key, argTable[key]) if argTableVal ~= nil then metaArgs[key] = argTableVal return argTableVal end end nilArgs[key] = 'h' return nil end metatable.__newindex = function (t, key, val) -- This function is called when a module tries to add a new value to the -- args table, or tries to change an existing value. if type(key) == 'string' then key = options.translate[key] end if options.readOnly then error( 'could not write to argument table key "' .. tostring(key) .. '"; the table is read-only', 2 ) elseif options.noOverwrite and args[key] ~= nil then error( 'could not write to argument table key "' .. tostring(key) .. '"; overwriting existing arguments is not permitted', 2 ) elseif val == nil then --[[ -- If the argument is to be overwritten with nil, we need to erase -- the value in metaArgs, so that __index, __pairs and __ipairs do -- not use a previous existing value, if present; and we also need -- to memoize the nil in nilArgs, so that the value isn't looked -- up in the argument tables if it is accessed again. --]] metaArgs[key] = nil nilArgs[key] = 'h' else metaArgs[key] = val end end local function translatenext(invariant) local k, v = next(invariant.t, invariant.k) invariant.k = k if k == nil then return nil elseif type(k) ~= 'string' or not options.backtranslate then return k, v else local backtranslate = options.backtranslate[k] if backtranslate == nil then -- Skip this one. This is a tail call, so this won't cause stack overflow return translatenext(invariant) else return backtranslate, v end end end metatable.__pairs = function () -- Called when pairs is run on the args table. if not metatable.donePairs then mergeArgs(argTables) metatable.donePairs = true end return translatenext, { t = metaArgs } end local function inext(t, i) -- This uses our __index metamethod local v = t[i + 1] if v ~= nil then return i + 1, v end end metatable.__ipairs = function (t) -- Called when ipairs is run on the args table. return inext, t, 0 end return args end return arguments 3134ecce8429b810d445e29eae115e2ae4c36c53 มอดูล:Documentation/config 828 8 10 2023-10-05T08:23:28Z PeachFullzZ 2 สร้างหน้าด้วย "---------------------------------------------------------------------------------------------------- -- -- Configuration for Module:Documentation -- -- Here you can set the values of the parameters and messages used in Module:Documentation to -- localise it to your wiki and your language. Unless specified otherwise, values given here -- should be string values. -----------------------------------------------------------..." Scribunto text/plain ---------------------------------------------------------------------------------------------------- -- -- Configuration for Module:Documentation -- -- Here you can set the values of the parameters and messages used in Module:Documentation to -- localise it to your wiki and your language. Unless specified otherwise, values given here -- should be string values. ---------------------------------------------------------------------------------------------------- local cfg = {} -- Do not edit this line. ---------------------------------------------------------------------------------------------------- -- Protection template configuration ---------------------------------------------------------------------------------------------------- -- cfg['protection-reason-edit'] -- The protection reason for edit-protected templates to pass to -- [[Module:Protection banner]]. cfg['protection-reason-edit'] = 'template' --[[ ---------------------------------------------------------------------------------------------------- -- Sandbox notice configuration -- -- On sandbox pages the module can display a template notifying users that the current page is a -- sandbox, and the location of test cases pages, etc. The module decides whether the page is a -- sandbox or not based on the value of cfg['sandbox-subpage']. The following settings configure the -- messages that the notices contains. ---------------------------------------------------------------------------------------------------- --]] -- cfg['sandbox-notice-image'] -- The image displayed in the sandbox notice. cfg['sandbox-notice-image'] = '[[File:Sandbox.svg|50px|alt=|link=]]' --[[ -- cfg['sandbox-notice-pagetype-template'] -- cfg['sandbox-notice-pagetype-module'] -- cfg['sandbox-notice-pagetype-other'] -- The page type of the sandbox page. The message that is displayed depends on the current subject -- namespace. This message is used in either cfg['sandbox-notice-blurb'] or -- cfg['sandbox-notice-diff-blurb']. --]] cfg['sandbox-notice-pagetype-template'] = '[[Wikipedia:Template test cases|template sandbox]] page' cfg['sandbox-notice-pagetype-module'] = '[[Wikipedia:Template test cases|module sandbox]] page' cfg['sandbox-notice-pagetype-other'] = 'sandbox page' --[[ -- cfg['sandbox-notice-blurb'] -- cfg['sandbox-notice-diff-blurb'] -- cfg['sandbox-notice-diff-display'] -- Either cfg['sandbox-notice-blurb'] or cfg['sandbox-notice-diff-blurb'] is the opening sentence -- of the sandbox notice. The latter has a diff link, but the former does not. $1 is the page -- type, which is either cfg['sandbox-notice-pagetype-template'], -- cfg['sandbox-notice-pagetype-module'] or cfg['sandbox-notice-pagetype-other'] depending what -- namespace we are in. $2 is a link to the main template page, and $3 is a diff link between -- the sandbox and the main template. The display value of the diff link is set by -- cfg['sandbox-notice-compare-link-display']. --]] cfg['sandbox-notice-blurb'] = 'This is the $1 for $2.' cfg['sandbox-notice-diff-blurb'] = 'This is the $1 for $2 ($3).' cfg['sandbox-notice-compare-link-display'] = 'diff' --[[ -- cfg['sandbox-notice-testcases-blurb'] -- cfg['sandbox-notice-testcases-link-display'] -- cfg['sandbox-notice-testcases-run-blurb'] -- cfg['sandbox-notice-testcases-run-link-display'] -- cfg['sandbox-notice-testcases-blurb'] is a sentence notifying the user that there is a test cases page -- corresponding to this sandbox that they can edit. $1 is a link to the test cases page. -- cfg['sandbox-notice-testcases-link-display'] is the display value for that link. -- cfg['sandbox-notice-testcases-run-blurb'] is a sentence notifying the user that there is a test cases page -- corresponding to this sandbox that they can edit, along with a link to run it. $1 is a link to the test -- cases page, and $2 is a link to the page to run it. -- cfg['sandbox-notice-testcases-run-link-display'] is the display value for the link to run the test -- cases. --]] cfg['sandbox-notice-testcases-blurb'] = 'See also the companion subpage for $1.' cfg['sandbox-notice-testcases-link-display'] = 'test cases' cfg['sandbox-notice-testcases-run-blurb'] = 'See also the companion subpage for $1 ($2).' cfg['sandbox-notice-testcases-run-link-display'] = 'run' -- cfg['sandbox-category'] -- A category to add to all template sandboxes. cfg['sandbox-category'] = 'Template sandboxes' ---------------------------------------------------------------------------------------------------- -- Start box configuration ---------------------------------------------------------------------------------------------------- -- cfg['documentation-icon-wikitext'] -- The wikitext for the icon shown at the top of the template. cfg['documentation-icon-wikitext'] = '[[File:Test Template Info-Icon - Version (2).svg|50px|link=|alt=]]' -- cfg['template-namespace-heading'] -- The heading shown in the template namespace. cfg['template-namespace-heading'] = 'Template documentation' -- cfg['module-namespace-heading'] -- The heading shown in the module namespace. cfg['module-namespace-heading'] = 'Module documentation' -- cfg['file-namespace-heading'] -- The heading shown in the file namespace. cfg['file-namespace-heading'] = 'Summary' -- cfg['other-namespaces-heading'] -- The heading shown in other namespaces. cfg['other-namespaces-heading'] = 'Documentation' -- cfg['view-link-display'] -- The text to display for "view" links. cfg['view-link-display'] = 'view' -- cfg['edit-link-display'] -- The text to display for "edit" links. cfg['edit-link-display'] = 'edit' -- cfg['history-link-display'] -- The text to display for "history" links. cfg['history-link-display'] = 'history' -- cfg['purge-link-display'] -- The text to display for "purge" links. cfg['purge-link-display'] = 'purge' -- cfg['create-link-display'] -- The text to display for "create" links. cfg['create-link-display'] = 'create' ---------------------------------------------------------------------------------------------------- -- Link box (end box) configuration ---------------------------------------------------------------------------------------------------- -- cfg['transcluded-from-blurb'] -- Notice displayed when the docs are transcluded from another page. $1 is a wikilink to that page. cfg['transcluded-from-blurb'] = 'The above [[Wikipedia:Template documentation|documentation]] is [[Help:Transclusion|transcluded]] from $1.' --[[ -- cfg['create-module-doc-blurb'] -- Notice displayed in the module namespace when the documentation subpage does not exist. -- $1 is a link to create the documentation page with the preload cfg['module-preload'] and the -- display cfg['create-link-display']. --]] cfg['create-module-doc-blurb'] = 'You might want to $1 a documentation page for this [[Wikipedia:Lua|Scribunto module]].' ---------------------------------------------------------------------------------------------------- -- Experiment blurb configuration ---------------------------------------------------------------------------------------------------- --[[ -- cfg['experiment-blurb-template'] -- cfg['experiment-blurb-module'] -- The experiment blurb is the text inviting editors to experiment in sandbox and test cases pages. -- It is only shown in the template and module namespaces. With the default English settings, it -- might look like this: -- -- Editors can experiment in this template's sandbox (edit | diff) and testcases (edit) pages. -- -- In this example, "sandbox", "edit", "diff", "testcases", and "edit" would all be links. -- -- There are two versions, cfg['experiment-blurb-template'] and cfg['experiment-blurb-module'], depending -- on what namespace we are in. -- -- Parameters: -- -- $1 is a link to the sandbox page. If the sandbox exists, it is in the following format: -- -- cfg['sandbox-link-display'] (cfg['sandbox-edit-link-display'] | cfg['compare-link-display']) -- -- If the sandbox doesn't exist, it is in the format: -- -- cfg['sandbox-link-display'] (cfg['sandbox-create-link-display'] | cfg['mirror-link-display']) -- -- The link for cfg['sandbox-create-link-display'] link preloads the page with cfg['template-sandbox-preload'] -- or cfg['module-sandbox-preload'], depending on the current namespace. The link for cfg['mirror-link-display'] -- loads a default edit summary of cfg['mirror-edit-summary']. -- -- $2 is a link to the test cases page. If the test cases page exists, it is in the following format: -- -- cfg['testcases-link-display'] (cfg['testcases-edit-link-display'] | cfg['testcases-run-link-display']) -- -- If the test cases page doesn't exist, it is in the format: -- -- cfg['testcases-link-display'] (cfg['testcases-create-link-display']) -- -- If the test cases page doesn't exist, the link for cfg['testcases-create-link-display'] preloads the -- page with cfg['template-testcases-preload'] or cfg['module-testcases-preload'], depending on the current -- namespace. --]] cfg['experiment-blurb-template'] = "Editors can experiment in this template's $1 and $2 pages." cfg['experiment-blurb-module'] = "Editors can experiment in this module's $1 and $2 pages." ---------------------------------------------------------------------------------------------------- -- Sandbox link configuration ---------------------------------------------------------------------------------------------------- -- cfg['sandbox-subpage'] -- The name of the template subpage typically used for sandboxes. cfg['sandbox-subpage'] = 'sandbox' -- cfg['template-sandbox-preload'] -- Preload file for template sandbox pages. cfg['template-sandbox-preload'] = 'Template:Documentation/preload-sandbox' -- cfg['module-sandbox-preload'] -- Preload file for Lua module sandbox pages. cfg['module-sandbox-preload'] = 'Template:Documentation/preload-module-sandbox' -- cfg['sandbox-link-display'] -- The text to display for "sandbox" links. cfg['sandbox-link-display'] = 'sandbox' -- cfg['sandbox-edit-link-display'] -- The text to display for sandbox "edit" links. cfg['sandbox-edit-link-display'] = 'edit' -- cfg['sandbox-create-link-display'] -- The text to display for sandbox "create" links. cfg['sandbox-create-link-display'] = 'create' -- cfg['compare-link-display'] -- The text to display for "compare" links. cfg['compare-link-display'] = 'diff' -- cfg['mirror-edit-summary'] -- The default edit summary to use when a user clicks the "mirror" link. $1 is a wikilink to the -- template page. cfg['mirror-edit-summary'] = 'Create sandbox version of $1' -- cfg['mirror-link-display'] -- The text to display for "mirror" links. cfg['mirror-link-display'] = 'mirror' -- cfg['mirror-link-preload'] -- The page to preload when a user clicks the "mirror" link. cfg['mirror-link-preload'] = 'Template:Documentation/mirror' ---------------------------------------------------------------------------------------------------- -- Test cases link configuration ---------------------------------------------------------------------------------------------------- -- cfg['testcases-subpage'] -- The name of the template subpage typically used for test cases. cfg['testcases-subpage'] = 'testcases' -- cfg['template-testcases-preload'] -- Preload file for template test cases pages. cfg['template-testcases-preload'] = 'Template:Documentation/preload-testcases' -- cfg['module-testcases-preload'] -- Preload file for Lua module test cases pages. cfg['module-testcases-preload'] = 'Template:Documentation/preload-module-testcases' -- cfg['testcases-link-display'] -- The text to display for "testcases" links. cfg['testcases-link-display'] = 'testcases' -- cfg['testcases-edit-link-display'] -- The text to display for test cases "edit" links. cfg['testcases-edit-link-display'] = 'edit' -- cfg['testcases-run-link-display'] -- The text to display for test cases "run" links. cfg['testcases-run-link-display'] = 'run' -- cfg['testcases-create-link-display'] -- The text to display for test cases "create" links. cfg['testcases-create-link-display'] = 'create' ---------------------------------------------------------------------------------------------------- -- Add categories blurb configuration ---------------------------------------------------------------------------------------------------- --[[ -- cfg['add-categories-blurb'] -- Text to direct users to add categories to the /doc subpage. Not used if the "content" or -- "docname fed" arguments are set, as then it is not clear where to add the categories. $1 is a -- link to the /doc subpage with a display value of cfg['doc-link-display']. --]] cfg['add-categories-blurb'] = 'Add categories to the $1 subpage.' -- cfg['doc-link-display'] -- The text to display when linking to the /doc subpage. cfg['doc-link-display'] = '/doc' ---------------------------------------------------------------------------------------------------- -- Subpages link configuration ---------------------------------------------------------------------------------------------------- --[[ -- cfg['subpages-blurb'] -- The "Subpages of this template" blurb. $1 is a link to the main template's subpages with a -- display value of cfg['subpages-link-display']. In the English version this blurb is simply -- the link followed by a period, and the link display provides the actual text. --]] cfg['subpages-blurb'] = '$1.' --[[ -- cfg['subpages-link-display'] -- The text to display for the "subpages of this page" link. $1 is cfg['template-pagetype'], -- cfg['module-pagetype'] or cfg['default-pagetype'], depending on whether the current page is in -- the template namespace, the module namespace, or another namespace. --]] cfg['subpages-link-display'] = 'Subpages of this $1' -- cfg['template-pagetype'] -- The pagetype to display for template pages. cfg['template-pagetype'] = 'template' -- cfg['module-pagetype'] -- The pagetype to display for Lua module pages. cfg['module-pagetype'] = 'module' -- cfg['default-pagetype'] -- The pagetype to display for pages other than templates or Lua modules. cfg['default-pagetype'] = 'page' ---------------------------------------------------------------------------------------------------- -- Doc link configuration ---------------------------------------------------------------------------------------------------- -- cfg['doc-subpage'] -- The name of the subpage typically used for documentation pages. cfg['doc-subpage'] = 'doc' -- cfg['docpage-preload'] -- Preload file for template documentation pages in all namespaces. cfg['docpage-preload'] = 'Template:Documentation/preload' -- cfg['module-preload'] -- Preload file for Lua module documentation pages. cfg['module-preload'] = 'Template:Documentation/preload-module-doc' ---------------------------------------------------------------------------------------------------- -- HTML and CSS configuration ---------------------------------------------------------------------------------------------------- -- cfg['templatestyles'] -- The name of the TemplateStyles page where CSS is kept. -- Sandbox CSS will be at Module:Documentation/sandbox/styles.css when needed. cfg['templatestyles'] = 'Module:Documentation/styles.css' -- cfg['container'] -- Class which can be used to set flex or grid CSS on the -- two child divs documentation and documentation-metadata cfg['container'] = 'documentation-container' -- cfg['main-div-classes'] -- Classes added to the main HTML "div" tag. cfg['main-div-classes'] = 'documentation' -- cfg['main-div-heading-class'] -- Class for the main heading for templates and modules and assoc. talk spaces cfg['main-div-heading-class'] = 'documentation-heading' -- cfg['start-box-class'] -- Class for the start box cfg['start-box-class'] = 'documentation-startbox' -- cfg['start-box-link-classes'] -- Classes used for the [view][edit][history] or [create] links in the start box. -- mw-editsection-like is per [[Wikipedia:Village pump (technical)/Archive 117]] cfg['start-box-link-classes'] = 'mw-editsection-like plainlinks' -- cfg['end-box-class'] -- Class for the end box. cfg['end-box-class'] = 'documentation-metadata' -- cfg['end-box-plainlinks'] -- Plainlinks cfg['end-box-plainlinks'] = 'plainlinks' -- cfg['toolbar-class'] -- Class added for toolbar links. cfg['toolbar-class'] = 'documentation-toolbar' -- cfg['clear'] -- Just used to clear things. cfg['clear'] = 'documentation-clear' ---------------------------------------------------------------------------------------------------- -- Tracking category configuration ---------------------------------------------------------------------------------------------------- -- cfg['display-strange-usage-category'] -- Set to true to enable output of cfg['strange-usage-category'] if the module is used on a /doc subpage -- or a /testcases subpage. This should be a boolean value (either true or false). cfg['display-strange-usage-category'] = true -- cfg['strange-usage-category'] -- Category to output if cfg['display-strange-usage-category'] is set to true and the module is used on a -- /doc subpage or a /testcases subpage. cfg['strange-usage-category'] = 'Wikipedia pages with strange ((documentation)) usage' --[[ ---------------------------------------------------------------------------------------------------- -- End configuration -- -- Don't edit anything below this line. ---------------------------------------------------------------------------------------------------- --]] return cfg 71b68ed73088f1a59d61acf06bbee9fde6677f03 11 10 2023-10-05T08:23:55Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Documentation/config]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain ---------------------------------------------------------------------------------------------------- -- -- Configuration for Module:Documentation -- -- Here you can set the values of the parameters and messages used in Module:Documentation to -- localise it to your wiki and your language. Unless specified otherwise, values given here -- should be string values. ---------------------------------------------------------------------------------------------------- local cfg = {} -- Do not edit this line. ---------------------------------------------------------------------------------------------------- -- Protection template configuration ---------------------------------------------------------------------------------------------------- -- cfg['protection-reason-edit'] -- The protection reason for edit-protected templates to pass to -- [[Module:Protection banner]]. cfg['protection-reason-edit'] = 'template' --[[ ---------------------------------------------------------------------------------------------------- -- Sandbox notice configuration -- -- On sandbox pages the module can display a template notifying users that the current page is a -- sandbox, and the location of test cases pages, etc. The module decides whether the page is a -- sandbox or not based on the value of cfg['sandbox-subpage']. The following settings configure the -- messages that the notices contains. ---------------------------------------------------------------------------------------------------- --]] -- cfg['sandbox-notice-image'] -- The image displayed in the sandbox notice. cfg['sandbox-notice-image'] = '[[File:Sandbox.svg|50px|alt=|link=]]' --[[ -- cfg['sandbox-notice-pagetype-template'] -- cfg['sandbox-notice-pagetype-module'] -- cfg['sandbox-notice-pagetype-other'] -- The page type of the sandbox page. The message that is displayed depends on the current subject -- namespace. This message is used in either cfg['sandbox-notice-blurb'] or -- cfg['sandbox-notice-diff-blurb']. --]] cfg['sandbox-notice-pagetype-template'] = '[[Wikipedia:Template test cases|template sandbox]] page' cfg['sandbox-notice-pagetype-module'] = '[[Wikipedia:Template test cases|module sandbox]] page' cfg['sandbox-notice-pagetype-other'] = 'sandbox page' --[[ -- cfg['sandbox-notice-blurb'] -- cfg['sandbox-notice-diff-blurb'] -- cfg['sandbox-notice-diff-display'] -- Either cfg['sandbox-notice-blurb'] or cfg['sandbox-notice-diff-blurb'] is the opening sentence -- of the sandbox notice. The latter has a diff link, but the former does not. $1 is the page -- type, which is either cfg['sandbox-notice-pagetype-template'], -- cfg['sandbox-notice-pagetype-module'] or cfg['sandbox-notice-pagetype-other'] depending what -- namespace we are in. $2 is a link to the main template page, and $3 is a diff link between -- the sandbox and the main template. The display value of the diff link is set by -- cfg['sandbox-notice-compare-link-display']. --]] cfg['sandbox-notice-blurb'] = 'This is the $1 for $2.' cfg['sandbox-notice-diff-blurb'] = 'This is the $1 for $2 ($3).' cfg['sandbox-notice-compare-link-display'] = 'diff' --[[ -- cfg['sandbox-notice-testcases-blurb'] -- cfg['sandbox-notice-testcases-link-display'] -- cfg['sandbox-notice-testcases-run-blurb'] -- cfg['sandbox-notice-testcases-run-link-display'] -- cfg['sandbox-notice-testcases-blurb'] is a sentence notifying the user that there is a test cases page -- corresponding to this sandbox that they can edit. $1 is a link to the test cases page. -- cfg['sandbox-notice-testcases-link-display'] is the display value for that link. -- cfg['sandbox-notice-testcases-run-blurb'] is a sentence notifying the user that there is a test cases page -- corresponding to this sandbox that they can edit, along with a link to run it. $1 is a link to the test -- cases page, and $2 is a link to the page to run it. -- cfg['sandbox-notice-testcases-run-link-display'] is the display value for the link to run the test -- cases. --]] cfg['sandbox-notice-testcases-blurb'] = 'See also the companion subpage for $1.' cfg['sandbox-notice-testcases-link-display'] = 'test cases' cfg['sandbox-notice-testcases-run-blurb'] = 'See also the companion subpage for $1 ($2).' cfg['sandbox-notice-testcases-run-link-display'] = 'run' -- cfg['sandbox-category'] -- A category to add to all template sandboxes. cfg['sandbox-category'] = 'Template sandboxes' ---------------------------------------------------------------------------------------------------- -- Start box configuration ---------------------------------------------------------------------------------------------------- -- cfg['documentation-icon-wikitext'] -- The wikitext for the icon shown at the top of the template. cfg['documentation-icon-wikitext'] = '[[File:Test Template Info-Icon - Version (2).svg|50px|link=|alt=]]' -- cfg['template-namespace-heading'] -- The heading shown in the template namespace. cfg['template-namespace-heading'] = 'Template documentation' -- cfg['module-namespace-heading'] -- The heading shown in the module namespace. cfg['module-namespace-heading'] = 'Module documentation' -- cfg['file-namespace-heading'] -- The heading shown in the file namespace. cfg['file-namespace-heading'] = 'Summary' -- cfg['other-namespaces-heading'] -- The heading shown in other namespaces. cfg['other-namespaces-heading'] = 'Documentation' -- cfg['view-link-display'] -- The text to display for "view" links. cfg['view-link-display'] = 'view' -- cfg['edit-link-display'] -- The text to display for "edit" links. cfg['edit-link-display'] = 'edit' -- cfg['history-link-display'] -- The text to display for "history" links. cfg['history-link-display'] = 'history' -- cfg['purge-link-display'] -- The text to display for "purge" links. cfg['purge-link-display'] = 'purge' -- cfg['create-link-display'] -- The text to display for "create" links. cfg['create-link-display'] = 'create' ---------------------------------------------------------------------------------------------------- -- Link box (end box) configuration ---------------------------------------------------------------------------------------------------- -- cfg['transcluded-from-blurb'] -- Notice displayed when the docs are transcluded from another page. $1 is a wikilink to that page. cfg['transcluded-from-blurb'] = 'The above [[Wikipedia:Template documentation|documentation]] is [[Help:Transclusion|transcluded]] from $1.' --[[ -- cfg['create-module-doc-blurb'] -- Notice displayed in the module namespace when the documentation subpage does not exist. -- $1 is a link to create the documentation page with the preload cfg['module-preload'] and the -- display cfg['create-link-display']. --]] cfg['create-module-doc-blurb'] = 'You might want to $1 a documentation page for this [[Wikipedia:Lua|Scribunto module]].' ---------------------------------------------------------------------------------------------------- -- Experiment blurb configuration ---------------------------------------------------------------------------------------------------- --[[ -- cfg['experiment-blurb-template'] -- cfg['experiment-blurb-module'] -- The experiment blurb is the text inviting editors to experiment in sandbox and test cases pages. -- It is only shown in the template and module namespaces. With the default English settings, it -- might look like this: -- -- Editors can experiment in this template's sandbox (edit | diff) and testcases (edit) pages. -- -- In this example, "sandbox", "edit", "diff", "testcases", and "edit" would all be links. -- -- There are two versions, cfg['experiment-blurb-template'] and cfg['experiment-blurb-module'], depending -- on what namespace we are in. -- -- Parameters: -- -- $1 is a link to the sandbox page. If the sandbox exists, it is in the following format: -- -- cfg['sandbox-link-display'] (cfg['sandbox-edit-link-display'] | cfg['compare-link-display']) -- -- If the sandbox doesn't exist, it is in the format: -- -- cfg['sandbox-link-display'] (cfg['sandbox-create-link-display'] | cfg['mirror-link-display']) -- -- The link for cfg['sandbox-create-link-display'] link preloads the page with cfg['template-sandbox-preload'] -- or cfg['module-sandbox-preload'], depending on the current namespace. The link for cfg['mirror-link-display'] -- loads a default edit summary of cfg['mirror-edit-summary']. -- -- $2 is a link to the test cases page. If the test cases page exists, it is in the following format: -- -- cfg['testcases-link-display'] (cfg['testcases-edit-link-display'] | cfg['testcases-run-link-display']) -- -- If the test cases page doesn't exist, it is in the format: -- -- cfg['testcases-link-display'] (cfg['testcases-create-link-display']) -- -- If the test cases page doesn't exist, the link for cfg['testcases-create-link-display'] preloads the -- page with cfg['template-testcases-preload'] or cfg['module-testcases-preload'], depending on the current -- namespace. --]] cfg['experiment-blurb-template'] = "Editors can experiment in this template's $1 and $2 pages." cfg['experiment-blurb-module'] = "Editors can experiment in this module's $1 and $2 pages." ---------------------------------------------------------------------------------------------------- -- Sandbox link configuration ---------------------------------------------------------------------------------------------------- -- cfg['sandbox-subpage'] -- The name of the template subpage typically used for sandboxes. cfg['sandbox-subpage'] = 'sandbox' -- cfg['template-sandbox-preload'] -- Preload file for template sandbox pages. cfg['template-sandbox-preload'] = 'Template:Documentation/preload-sandbox' -- cfg['module-sandbox-preload'] -- Preload file for Lua module sandbox pages. cfg['module-sandbox-preload'] = 'Template:Documentation/preload-module-sandbox' -- cfg['sandbox-link-display'] -- The text to display for "sandbox" links. cfg['sandbox-link-display'] = 'sandbox' -- cfg['sandbox-edit-link-display'] -- The text to display for sandbox "edit" links. cfg['sandbox-edit-link-display'] = 'edit' -- cfg['sandbox-create-link-display'] -- The text to display for sandbox "create" links. cfg['sandbox-create-link-display'] = 'create' -- cfg['compare-link-display'] -- The text to display for "compare" links. cfg['compare-link-display'] = 'diff' -- cfg['mirror-edit-summary'] -- The default edit summary to use when a user clicks the "mirror" link. $1 is a wikilink to the -- template page. cfg['mirror-edit-summary'] = 'Create sandbox version of $1' -- cfg['mirror-link-display'] -- The text to display for "mirror" links. cfg['mirror-link-display'] = 'mirror' -- cfg['mirror-link-preload'] -- The page to preload when a user clicks the "mirror" link. cfg['mirror-link-preload'] = 'Template:Documentation/mirror' ---------------------------------------------------------------------------------------------------- -- Test cases link configuration ---------------------------------------------------------------------------------------------------- -- cfg['testcases-subpage'] -- The name of the template subpage typically used for test cases. cfg['testcases-subpage'] = 'testcases' -- cfg['template-testcases-preload'] -- Preload file for template test cases pages. cfg['template-testcases-preload'] = 'Template:Documentation/preload-testcases' -- cfg['module-testcases-preload'] -- Preload file for Lua module test cases pages. cfg['module-testcases-preload'] = 'Template:Documentation/preload-module-testcases' -- cfg['testcases-link-display'] -- The text to display for "testcases" links. cfg['testcases-link-display'] = 'testcases' -- cfg['testcases-edit-link-display'] -- The text to display for test cases "edit" links. cfg['testcases-edit-link-display'] = 'edit' -- cfg['testcases-run-link-display'] -- The text to display for test cases "run" links. cfg['testcases-run-link-display'] = 'run' -- cfg['testcases-create-link-display'] -- The text to display for test cases "create" links. cfg['testcases-create-link-display'] = 'create' ---------------------------------------------------------------------------------------------------- -- Add categories blurb configuration ---------------------------------------------------------------------------------------------------- --[[ -- cfg['add-categories-blurb'] -- Text to direct users to add categories to the /doc subpage. Not used if the "content" or -- "docname fed" arguments are set, as then it is not clear where to add the categories. $1 is a -- link to the /doc subpage with a display value of cfg['doc-link-display']. --]] cfg['add-categories-blurb'] = 'Add categories to the $1 subpage.' -- cfg['doc-link-display'] -- The text to display when linking to the /doc subpage. cfg['doc-link-display'] = '/doc' ---------------------------------------------------------------------------------------------------- -- Subpages link configuration ---------------------------------------------------------------------------------------------------- --[[ -- cfg['subpages-blurb'] -- The "Subpages of this template" blurb. $1 is a link to the main template's subpages with a -- display value of cfg['subpages-link-display']. In the English version this blurb is simply -- the link followed by a period, and the link display provides the actual text. --]] cfg['subpages-blurb'] = '$1.' --[[ -- cfg['subpages-link-display'] -- The text to display for the "subpages of this page" link. $1 is cfg['template-pagetype'], -- cfg['module-pagetype'] or cfg['default-pagetype'], depending on whether the current page is in -- the template namespace, the module namespace, or another namespace. --]] cfg['subpages-link-display'] = 'Subpages of this $1' -- cfg['template-pagetype'] -- The pagetype to display for template pages. cfg['template-pagetype'] = 'template' -- cfg['module-pagetype'] -- The pagetype to display for Lua module pages. cfg['module-pagetype'] = 'module' -- cfg['default-pagetype'] -- The pagetype to display for pages other than templates or Lua modules. cfg['default-pagetype'] = 'page' ---------------------------------------------------------------------------------------------------- -- Doc link configuration ---------------------------------------------------------------------------------------------------- -- cfg['doc-subpage'] -- The name of the subpage typically used for documentation pages. cfg['doc-subpage'] = 'doc' -- cfg['docpage-preload'] -- Preload file for template documentation pages in all namespaces. cfg['docpage-preload'] = 'Template:Documentation/preload' -- cfg['module-preload'] -- Preload file for Lua module documentation pages. cfg['module-preload'] = 'Template:Documentation/preload-module-doc' ---------------------------------------------------------------------------------------------------- -- HTML and CSS configuration ---------------------------------------------------------------------------------------------------- -- cfg['templatestyles'] -- The name of the TemplateStyles page where CSS is kept. -- Sandbox CSS will be at Module:Documentation/sandbox/styles.css when needed. cfg['templatestyles'] = 'Module:Documentation/styles.css' -- cfg['container'] -- Class which can be used to set flex or grid CSS on the -- two child divs documentation and documentation-metadata cfg['container'] = 'documentation-container' -- cfg['main-div-classes'] -- Classes added to the main HTML "div" tag. cfg['main-div-classes'] = 'documentation' -- cfg['main-div-heading-class'] -- Class for the main heading for templates and modules and assoc. talk spaces cfg['main-div-heading-class'] = 'documentation-heading' -- cfg['start-box-class'] -- Class for the start box cfg['start-box-class'] = 'documentation-startbox' -- cfg['start-box-link-classes'] -- Classes used for the [view][edit][history] or [create] links in the start box. -- mw-editsection-like is per [[Wikipedia:Village pump (technical)/Archive 117]] cfg['start-box-link-classes'] = 'mw-editsection-like plainlinks' -- cfg['end-box-class'] -- Class for the end box. cfg['end-box-class'] = 'documentation-metadata' -- cfg['end-box-plainlinks'] -- Plainlinks cfg['end-box-plainlinks'] = 'plainlinks' -- cfg['toolbar-class'] -- Class added for toolbar links. cfg['toolbar-class'] = 'documentation-toolbar' -- cfg['clear'] -- Just used to clear things. cfg['clear'] = 'documentation-clear' ---------------------------------------------------------------------------------------------------- -- Tracking category configuration ---------------------------------------------------------------------------------------------------- -- cfg['display-strange-usage-category'] -- Set to true to enable output of cfg['strange-usage-category'] if the module is used on a /doc subpage -- or a /testcases subpage. This should be a boolean value (either true or false). cfg['display-strange-usage-category'] = true -- cfg['strange-usage-category'] -- Category to output if cfg['display-strange-usage-category'] is set to true and the module is used on a -- /doc subpage or a /testcases subpage. cfg['strange-usage-category'] = 'Wikipedia pages with strange ((documentation)) usage' --[[ ---------------------------------------------------------------------------------------------------- -- End configuration -- -- Don't edit anything below this line. ---------------------------------------------------------------------------------------------------- --]] return cfg 71b68ed73088f1a59d61acf06bbee9fde6677f03 12 11 2023-10-05T08:36:55Z PeachFullzZ 2 Scribunto text/plain ---------------------------------------------------------------------------------------------------- -- -- Configuration for Module:Documentation -- -- Here you can set the values of the parameters and messages used in Module:Documentation to -- localise it to your wiki and your language. Unless specified otherwise, values given here -- should be string values. ---------------------------------------------------------------------------------------------------- local cfg = {} -- Do not edit this line. ---------------------------------------------------------------------------------------------------- -- Protection template configuration ---------------------------------------------------------------------------------------------------- -- cfg['protection-reason-edit'] -- The protection reason for edit-protected templates to pass to -- [[Module:Protection banner]]. cfg['protection-reason-edit'] = 'template' --[[ ---------------------------------------------------------------------------------------------------- -- Sandbox notice configuration -- -- On sandbox pages the module can display a template notifying users that the current page is a -- sandbox, and the location of test cases pages, etc. The module decides whether the page is a -- sandbox or not based on the value of cfg['sandbox-subpage']. The following settings configure the -- messages that the notices contains. ---------------------------------------------------------------------------------------------------- --]] -- cfg['sandbox-notice-image'] -- The image displayed in the sandbox notice. cfg['sandbox-notice-image'] = '[[File:Sandbox.svg|50px|alt=|link=]]' --[[ -- cfg['sandbox-notice-pagetype-template'] -- cfg['sandbox-notice-pagetype-module'] -- cfg['sandbox-notice-pagetype-other'] -- The page type of the sandbox page. The message that is displayed depends on the current subject -- namespace. This message is used in either cfg['sandbox-notice-blurb'] or -- cfg['sandbox-notice-diff-blurb']. --]] cfg['sandbox-notice-pagetype-template'] = '[[Wikipedia:Template test cases|template sandbox]] page' cfg['sandbox-notice-pagetype-module'] = '[[Wikipedia:Template test cases|module sandbox]] page' cfg['sandbox-notice-pagetype-other'] = 'sandbox page' --[[ -- cfg['sandbox-notice-blurb'] -- cfg['sandbox-notice-diff-blurb'] -- cfg['sandbox-notice-diff-display'] -- Either cfg['sandbox-notice-blurb'] or cfg['sandbox-notice-diff-blurb'] is the opening sentence -- of the sandbox notice. The latter has a diff link, but the former does not. $1 is the page -- type, which is either cfg['sandbox-notice-pagetype-template'], -- cfg['sandbox-notice-pagetype-module'] or cfg['sandbox-notice-pagetype-other'] depending what -- namespace we are in. $2 is a link to the main template page, and $3 is a diff link between -- the sandbox and the main template. The display value of the diff link is set by -- cfg['sandbox-notice-compare-link-display']. --]] cfg['sandbox-notice-blurb'] = 'This is the $1 for $2.' cfg['sandbox-notice-diff-blurb'] = 'This is the $1 for $2 ($3).' cfg['sandbox-notice-compare-link-display'] = 'diff' --[[ -- cfg['sandbox-notice-testcases-blurb'] -- cfg['sandbox-notice-testcases-link-display'] -- cfg['sandbox-notice-testcases-run-blurb'] -- cfg['sandbox-notice-testcases-run-link-display'] -- cfg['sandbox-notice-testcases-blurb'] is a sentence notifying the user that there is a test cases page -- corresponding to this sandbox that they can edit. $1 is a link to the test cases page. -- cfg['sandbox-notice-testcases-link-display'] is the display value for that link. -- cfg['sandbox-notice-testcases-run-blurb'] is a sentence notifying the user that there is a test cases page -- corresponding to this sandbox that they can edit, along with a link to run it. $1 is a link to the test -- cases page, and $2 is a link to the page to run it. -- cfg['sandbox-notice-testcases-run-link-display'] is the display value for the link to run the test -- cases. --]] cfg['sandbox-notice-testcases-blurb'] = 'See also the companion subpage for $1.' cfg['sandbox-notice-testcases-link-display'] = 'test cases' cfg['sandbox-notice-testcases-run-blurb'] = 'See also the companion subpage for $1 ($2).' cfg['sandbox-notice-testcases-run-link-display'] = 'run' -- cfg['sandbox-category'] -- A category to add to all template sandboxes. cfg['sandbox-category'] = 'Template sandboxes' ---------------------------------------------------------------------------------------------------- -- Start box configuration ---------------------------------------------------------------------------------------------------- -- cfg['documentation-icon-wikitext'] -- The wikitext for the icon shown at the top of the template. cfg['documentation-icon-wikitext'] = '[[File:Test Template Info-Icon - Version (2).svg|50px|link=|alt=]]' -- cfg['template-namespace-heading'] -- The heading shown in the template namespace. cfg['template-namespace-heading'] = 'Template documentation' -- cfg['module-namespace-heading'] -- The heading shown in the module namespace. cfg['module-namespace-heading'] = 'Module documentation' -- cfg['file-namespace-heading'] -- The heading shown in the file namespace. cfg['file-namespace-heading'] = 'Summary' -- cfg['other-namespaces-heading'] -- The heading shown in other namespaces. cfg['other-namespaces-heading'] = 'Documentation' -- cfg['view-link-display'] -- The text to display for "view" links. cfg['view-link-display'] = 'ดู' -- cfg['edit-link-display'] -- The text to display for "edit" links. cfg['edit-link-display'] = 'แก้ไข' -- cfg['history-link-display'] -- The text to display for "history" links. cfg['history-link-display'] = 'ประวัติ' -- cfg['purge-link-display'] -- The text to display for "purge" links. cfg['purge-link-display'] = 'purge' -- cfg['create-link-display'] -- The text to display for "create" links. cfg['create-link-display'] = 'สร้าง' ---------------------------------------------------------------------------------------------------- -- Link box (end box) configuration ---------------------------------------------------------------------------------------------------- -- cfg['transcluded-from-blurb'] -- Notice displayed when the docs are transcluded from another page. $1 is a wikilink to that page. cfg['transcluded-from-blurb'] = 'The above [[Wikipedia:Template documentation|documentation]] is [[Help:Transclusion|transcluded]] from $1.' --[[ -- cfg['create-module-doc-blurb'] -- Notice displayed in the module namespace when the documentation subpage does not exist. -- $1 is a link to create the documentation page with the preload cfg['module-preload'] and the -- display cfg['create-link-display']. --]] cfg['create-module-doc-blurb'] = 'You might want to $1 a documentation page for this [[Wikipedia:Lua|Scribunto module]].' ---------------------------------------------------------------------------------------------------- -- Experiment blurb configuration ---------------------------------------------------------------------------------------------------- --[[ -- cfg['experiment-blurb-template'] -- cfg['experiment-blurb-module'] -- The experiment blurb is the text inviting editors to experiment in sandbox and test cases pages. -- It is only shown in the template and module namespaces. With the default English settings, it -- might look like this: -- -- Editors can experiment in this template's sandbox (edit | diff) and testcases (edit) pages. -- -- In this example, "sandbox", "edit", "diff", "testcases", and "edit" would all be links. -- -- There are two versions, cfg['experiment-blurb-template'] and cfg['experiment-blurb-module'], depending -- on what namespace we are in. -- -- Parameters: -- -- $1 is a link to the sandbox page. If the sandbox exists, it is in the following format: -- -- cfg['sandbox-link-display'] (cfg['sandbox-edit-link-display'] | cfg['compare-link-display']) -- -- If the sandbox doesn't exist, it is in the format: -- -- cfg['sandbox-link-display'] (cfg['sandbox-create-link-display'] | cfg['mirror-link-display']) -- -- The link for cfg['sandbox-create-link-display'] link preloads the page with cfg['template-sandbox-preload'] -- or cfg['module-sandbox-preload'], depending on the current namespace. The link for cfg['mirror-link-display'] -- loads a default edit summary of cfg['mirror-edit-summary']. -- -- $2 is a link to the test cases page. If the test cases page exists, it is in the following format: -- -- cfg['testcases-link-display'] (cfg['testcases-edit-link-display'] | cfg['testcases-run-link-display']) -- -- If the test cases page doesn't exist, it is in the format: -- -- cfg['testcases-link-display'] (cfg['testcases-create-link-display']) -- -- If the test cases page doesn't exist, the link for cfg['testcases-create-link-display'] preloads the -- page with cfg['template-testcases-preload'] or cfg['module-testcases-preload'], depending on the current -- namespace. --]] cfg['experiment-blurb-template'] = "ผู้แก้ไขสามารถทดลองใช้หน้า$1 และ$2 ของแม่แบบนี้ได้" cfg['experiment-blurb-module'] = "ผู้แก้ไขสามารถทดลองใช้หน้า$1 และ$2 ของมอดูลนี้ได้" ---------------------------------------------------------------------------------------------------- -- Sandbox link configuration ---------------------------------------------------------------------------------------------------- -- cfg['sandbox-subpage'] -- The name of the template subpage typically used for sandboxes. cfg['sandbox-subpage'] = 'กระบะทราย' -- cfg['template-sandbox-preload'] -- Preload file for template sandbox pages. cfg['template-sandbox-preload'] = 'Template:Documentation/preload-sandbox' -- cfg['module-sandbox-preload'] -- Preload file for Lua module sandbox pages. cfg['module-sandbox-preload'] = 'Template:Documentation/preload-module-sandbox' -- cfg['sandbox-link-display'] -- The text to display for "sandbox" links. cfg['sandbox-link-display'] = 'กระบะทราย' -- cfg['sandbox-edit-link-display'] -- The text to display for sandbox "edit" links. cfg['sandbox-edit-link-display'] = 'แก้ไข' -- cfg['sandbox-create-link-display'] -- The text to display for sandbox "create" links. cfg['sandbox-create-link-display'] = 'สร้าง' -- cfg['compare-link-display'] -- The text to display for "compare" links. cfg['compare-link-display'] = 'diff' -- cfg['mirror-edit-summary'] -- The default edit summary to use when a user clicks the "mirror" link. $1 is a wikilink to the -- template page. cfg['mirror-edit-summary'] = 'Create sandbox version of $1' -- cfg['mirror-link-display'] -- The text to display for "mirror" links. cfg['mirror-link-display'] = 'mirror' -- cfg['mirror-link-preload'] -- The page to preload when a user clicks the "mirror" link. cfg['mirror-link-preload'] = 'Template:Documentation/mirror' ---------------------------------------------------------------------------------------------------- -- Test cases link configuration ---------------------------------------------------------------------------------------------------- -- cfg['testcases-subpage'] -- The name of the template subpage typically used for test cases. cfg['testcases-subpage'] = 'testcases' -- cfg['template-testcases-preload'] -- Preload file for template test cases pages. cfg['template-testcases-preload'] = 'Template:Documentation/preload-testcases' -- cfg['module-testcases-preload'] -- Preload file for Lua module test cases pages. cfg['module-testcases-preload'] = 'Template:Documentation/preload-module-testcases' -- cfg['testcases-link-display'] -- The text to display for "testcases" links. cfg['testcases-link-display'] = 'testcases' -- cfg['testcases-edit-link-display'] -- The text to display for test cases "edit" links. cfg['testcases-edit-link-display'] = 'แก้ไข' -- cfg['testcases-run-link-display'] -- The text to display for test cases "run" links. cfg['testcases-run-link-display'] = 'run' -- cfg['testcases-create-link-display'] -- The text to display for test cases "create" links. cfg['testcases-create-link-display'] = 'สร้าง' ---------------------------------------------------------------------------------------------------- -- Add categories blurb configuration ---------------------------------------------------------------------------------------------------- --[[ -- cfg['add-categories-blurb'] -- Text to direct users to add categories to the /doc subpage. Not used if the "content" or -- "docname fed" arguments are set, as then it is not clear where to add the categories. $1 is a -- link to the /doc subpage with a display value of cfg['doc-link-display']. --]] cfg['add-categories-blurb'] = 'Add categories to the $1 subpage.' -- cfg['doc-link-display'] -- The text to display when linking to the /doc subpage. cfg['doc-link-display'] = '/doc' ---------------------------------------------------------------------------------------------------- -- Subpages link configuration ---------------------------------------------------------------------------------------------------- --[[ -- cfg['subpages-blurb'] -- The "Subpages of this template" blurb. $1 is a link to the main template's subpages with a -- display value of cfg['subpages-link-display']. In the English version this blurb is simply -- the link followed by a period, and the link display provides the actual text. --]] cfg['subpages-blurb'] = '$1.' --[[ -- cfg['subpages-link-display'] -- The text to display for the "subpages of this page" link. $1 is cfg['template-pagetype'], -- cfg['module-pagetype'] or cfg['default-pagetype'], depending on whether the current page is in -- the template namespace, the module namespace, or another namespace. --]] cfg['subpages-link-display'] = 'Subpages of this $1' -- cfg['template-pagetype'] -- The pagetype to display for template pages. cfg['template-pagetype'] = 'แม่แบบ' -- cfg['module-pagetype'] -- The pagetype to display for Lua module pages. cfg['module-pagetype'] = 'มอดูล' -- cfg['default-pagetype'] -- The pagetype to display for pages other than templates or Lua modules. cfg['default-pagetype'] = 'หนัา' ---------------------------------------------------------------------------------------------------- -- Doc link configuration ---------------------------------------------------------------------------------------------------- -- cfg['doc-subpage'] -- The name of the subpage typically used for documentation pages. cfg['doc-subpage'] = 'doc' -- cfg['docpage-preload'] -- Preload file for template documentation pages in all namespaces. cfg['docpage-preload'] = 'Template:Documentation/preload' -- cfg['module-preload'] -- Preload file for Lua module documentation pages. cfg['module-preload'] = 'Template:Documentation/preload-module-doc' ---------------------------------------------------------------------------------------------------- -- HTML and CSS configuration ---------------------------------------------------------------------------------------------------- -- cfg['templatestyles'] -- The name of the TemplateStyles page where CSS is kept. -- Sandbox CSS will be at Module:Documentation/sandbox/styles.css when needed. cfg['templatestyles'] = 'Module:Documentation/styles.css' -- cfg['container'] -- Class which can be used to set flex or grid CSS on the -- two child divs documentation and documentation-metadata cfg['container'] = 'documentation-container' -- cfg['main-div-classes'] -- Classes added to the main HTML "div" tag. cfg['main-div-classes'] = 'documentation' -- cfg['main-div-heading-class'] -- Class for the main heading for templates and modules and assoc. talk spaces cfg['main-div-heading-class'] = 'documentation-heading' -- cfg['start-box-class'] -- Class for the start box cfg['start-box-class'] = 'documentation-startbox' -- cfg['start-box-link-classes'] -- Classes used for the [view][edit][history] or [create] links in the start box. -- mw-editsection-like is per [[Wikipedia:Village pump (technical)/Archive 117]] cfg['start-box-link-classes'] = 'mw-editsection-like plainlinks' -- cfg['end-box-class'] -- Class for the end box. cfg['end-box-class'] = 'documentation-metadata' -- cfg['end-box-plainlinks'] -- Plainlinks cfg['end-box-plainlinks'] = 'plainlinks' -- cfg['toolbar-class'] -- Class added for toolbar links. cfg['toolbar-class'] = 'documentation-toolbar' -- cfg['clear'] -- Just used to clear things. cfg['clear'] = 'documentation-clear' ---------------------------------------------------------------------------------------------------- -- Tracking category configuration ---------------------------------------------------------------------------------------------------- -- cfg['display-strange-usage-category'] -- Set to true to enable output of cfg['strange-usage-category'] if the module is used on a /doc subpage -- or a /testcases subpage. This should be a boolean value (either true or false). cfg['display-strange-usage-category'] = true -- cfg['strange-usage-category'] -- Category to output if cfg['display-strange-usage-category'] is set to true and the module is used on a -- /doc subpage or a /testcases subpage. cfg['strange-usage-category'] = 'Wikipedia pages with strange ((documentation)) usage' --[[ ---------------------------------------------------------------------------------------------------- -- End configuration -- -- Don't edit anything below this line. ---------------------------------------------------------------------------------------------------- --]] return cfg 6e6c8bf11fa13626a204fbd8e06c377386f9461b 13 12 2023-10-05T08:46:59Z PeachFullzZ 2 Scribunto text/plain ---------------------------------------------------------------------------------------------------- -- -- Configuration for Module:Documentation -- -- Here you can set the values of the parameters and messages used in Module:Documentation to -- localise it to your wiki and your language. Unless specified otherwise, values given here -- should be string values. ---------------------------------------------------------------------------------------------------- local cfg = {} -- Do not edit this line. ---------------------------------------------------------------------------------------------------- -- Protection template configuration ---------------------------------------------------------------------------------------------------- -- cfg['protection-reason-edit'] -- The protection reason for edit-protected templates to pass to -- [[Module:Protection banner]]. cfg['protection-reason-edit'] = 'template' --[[ ---------------------------------------------------------------------------------------------------- -- Sandbox notice configuration -- -- On sandbox pages the module can display a template notifying users that the current page is a -- sandbox, and the location of test cases pages, etc. The module decides whether the page is a -- sandbox or not based on the value of cfg['sandbox-subpage']. The following settings configure the -- messages that the notices contains. ---------------------------------------------------------------------------------------------------- --]] -- cfg['sandbox-notice-image'] -- The image displayed in the sandbox notice. cfg['sandbox-notice-image'] = '[[File:Sandbox.svg|50px|alt=|link=]]' --[[ -- cfg['sandbox-notice-pagetype-template'] -- cfg['sandbox-notice-pagetype-module'] -- cfg['sandbox-notice-pagetype-other'] -- The page type of the sandbox page. The message that is displayed depends on the current subject -- namespace. This message is used in either cfg['sandbox-notice-blurb'] or -- cfg['sandbox-notice-diff-blurb']. --]] cfg['sandbox-notice-pagetype-template'] = '[[Wikipedia:Template test cases|template sandbox]] page' cfg['sandbox-notice-pagetype-module'] = '[[Wikipedia:Template test cases|module sandbox]] page' cfg['sandbox-notice-pagetype-other'] = 'sandbox page' --[[ -- cfg['sandbox-notice-blurb'] -- cfg['sandbox-notice-diff-blurb'] -- cfg['sandbox-notice-diff-display'] -- Either cfg['sandbox-notice-blurb'] or cfg['sandbox-notice-diff-blurb'] is the opening sentence -- of the sandbox notice. The latter has a diff link, but the former does not. $1 is the page -- type, which is either cfg['sandbox-notice-pagetype-template'], -- cfg['sandbox-notice-pagetype-module'] or cfg['sandbox-notice-pagetype-other'] depending what -- namespace we are in. $2 is a link to the main template page, and $3 is a diff link between -- the sandbox and the main template. The display value of the diff link is set by -- cfg['sandbox-notice-compare-link-display']. --]] cfg['sandbox-notice-blurb'] = 'This is the $1 for $2.' cfg['sandbox-notice-diff-blurb'] = 'This is the $1 for $2 ($3).' cfg['sandbox-notice-compare-link-display'] = 'diff' --[[ -- cfg['sandbox-notice-testcases-blurb'] -- cfg['sandbox-notice-testcases-link-display'] -- cfg['sandbox-notice-testcases-run-blurb'] -- cfg['sandbox-notice-testcases-run-link-display'] -- cfg['sandbox-notice-testcases-blurb'] is a sentence notifying the user that there is a test cases page -- corresponding to this sandbox that they can edit. $1 is a link to the test cases page. -- cfg['sandbox-notice-testcases-link-display'] is the display value for that link. -- cfg['sandbox-notice-testcases-run-blurb'] is a sentence notifying the user that there is a test cases page -- corresponding to this sandbox that they can edit, along with a link to run it. $1 is a link to the test -- cases page, and $2 is a link to the page to run it. -- cfg['sandbox-notice-testcases-run-link-display'] is the display value for the link to run the test -- cases. --]] cfg['sandbox-notice-testcases-blurb'] = 'See also the companion subpage for $1.' cfg['sandbox-notice-testcases-link-display'] = 'test cases' cfg['sandbox-notice-testcases-run-blurb'] = 'See also the companion subpage for $1 ($2).' cfg['sandbox-notice-testcases-run-link-display'] = 'run' -- cfg['sandbox-category'] -- A category to add to all template sandboxes. cfg['sandbox-category'] = 'Template sandboxes' ---------------------------------------------------------------------------------------------------- -- Start box configuration ---------------------------------------------------------------------------------------------------- -- cfg['documentation-icon-wikitext'] -- The wikitext for the icon shown at the top of the template. cfg['documentation-icon-wikitext'] = '[[File:Test Template Info-Icon - Version (2).svg|50px|link=|alt=]]' -- cfg['template-namespace-heading'] -- The heading shown in the template namespace. cfg['template-namespace-heading'] = 'แม่แบบเอกสารประกอบ' -- cfg['module-namespace-heading'] -- The heading shown in the module namespace. cfg['module-namespace-heading'] = 'มอดูลเอกสารประกอบ' -- cfg['file-namespace-heading'] -- The heading shown in the file namespace. cfg['file-namespace-heading'] = 'Summary' -- cfg['other-namespaces-heading'] -- The heading shown in other namespaces. cfg['other-namespaces-heading'] = 'เอกสารประกอบ' -- cfg['view-link-display'] -- The text to display for "view" links. cfg['view-link-display'] = 'ดู' -- cfg['edit-link-display'] -- The text to display for "edit" links. cfg['edit-link-display'] = 'แก้ไข' -- cfg['history-link-display'] -- The text to display for "history" links. cfg['history-link-display'] = 'ประวัติ' -- cfg['purge-link-display'] -- The text to display for "purge" links. cfg['purge-link-display'] = 'ล้าง' -- cfg['create-link-display'] -- The text to display for "create" links. cfg['create-link-display'] = 'สร้าง' ---------------------------------------------------------------------------------------------------- -- Link box (end box) configuration ---------------------------------------------------------------------------------------------------- -- cfg['transcluded-from-blurb'] -- Notice displayed when the docs are transcluded from another page. $1 is a wikilink to that page. cfg['transcluded-from-blurb'] = 'The above [[Wikipedia:Template documentation|documentation]] is [[Help:Transclusion|transcluded]] from $1.' --[[ -- cfg['create-module-doc-blurb'] -- Notice displayed in the module namespace when the documentation subpage does not exist. -- $1 is a link to create the documentation page with the preload cfg['module-preload'] and the -- display cfg['create-link-display']. --]] cfg['create-module-doc-blurb'] = 'You might want to $1 a documentation page for this [[Wikipedia:Lua|Scribunto module]].' ---------------------------------------------------------------------------------------------------- -- Experiment blurb configuration ---------------------------------------------------------------------------------------------------- --[[ -- cfg['experiment-blurb-template'] -- cfg['experiment-blurb-module'] -- The experiment blurb is the text inviting editors to experiment in sandbox and test cases pages. -- It is only shown in the template and module namespaces. With the default English settings, it -- might look like this: -- -- Editors can experiment in this template's sandbox (edit | diff) and testcases (edit) pages. -- -- In this example, "sandbox", "edit", "diff", "testcases", and "edit" would all be links. -- -- There are two versions, cfg['experiment-blurb-template'] and cfg['experiment-blurb-module'], depending -- on what namespace we are in. -- -- Parameters: -- -- $1 is a link to the sandbox page. If the sandbox exists, it is in the following format: -- -- cfg['sandbox-link-display'] (cfg['sandbox-edit-link-display'] | cfg['compare-link-display']) -- -- If the sandbox doesn't exist, it is in the format: -- -- cfg['sandbox-link-display'] (cfg['sandbox-create-link-display'] | cfg['mirror-link-display']) -- -- The link for cfg['sandbox-create-link-display'] link preloads the page with cfg['template-sandbox-preload'] -- or cfg['module-sandbox-preload'], depending on the current namespace. The link for cfg['mirror-link-display'] -- loads a default edit summary of cfg['mirror-edit-summary']. -- -- $2 is a link to the test cases page. If the test cases page exists, it is in the following format: -- -- cfg['testcases-link-display'] (cfg['testcases-edit-link-display'] | cfg['testcases-run-link-display']) -- -- If the test cases page doesn't exist, it is in the format: -- -- cfg['testcases-link-display'] (cfg['testcases-create-link-display']) -- -- If the test cases page doesn't exist, the link for cfg['testcases-create-link-display'] preloads the -- page with cfg['template-testcases-preload'] or cfg['module-testcases-preload'], depending on the current -- namespace. --]] cfg['experiment-blurb-template'] = "ผู้แก้ไขสามารถนำแม่แบบนี้ไปทดลองใช้ในหน้า$1 และ$2ได้" cfg['experiment-blurb-module'] = "ผู้แก้ไขสามารถนำมอดูลนี้ไปทดลองใช้ในหน้า$1 และ$2ได้" ---------------------------------------------------------------------------------------------------- -- Sandbox link configuration ---------------------------------------------------------------------------------------------------- -- cfg['sandbox-subpage'] -- The name of the template subpage typically used for sandboxes. cfg['sandbox-subpage'] = 'กระบะทราย' -- cfg['template-sandbox-preload'] -- Preload file for template sandbox pages. cfg['template-sandbox-preload'] = 'Template:Documentation/preload-sandbox' -- cfg['module-sandbox-preload'] -- Preload file for Lua module sandbox pages. cfg['module-sandbox-preload'] = 'Template:Documentation/preload-module-sandbox' -- cfg['sandbox-link-display'] -- The text to display for "sandbox" links. cfg['sandbox-link-display'] = 'กระบะทราย' -- cfg['sandbox-edit-link-display'] -- The text to display for sandbox "edit" links. cfg['sandbox-edit-link-display'] = 'แก้ไข' -- cfg['sandbox-create-link-display'] -- The text to display for sandbox "create" links. cfg['sandbox-create-link-display'] = 'สร้าง' -- cfg['compare-link-display'] -- The text to display for "compare" links. cfg['compare-link-display'] = 'diff' -- cfg['mirror-edit-summary'] -- The default edit summary to use when a user clicks the "mirror" link. $1 is a wikilink to the -- template page. cfg['mirror-edit-summary'] = 'Create sandbox version of $1' -- cfg['mirror-link-display'] -- The text to display for "mirror" links. cfg['mirror-link-display'] = 'คัดแบบ' -- cfg['mirror-link-preload'] -- The page to preload when a user clicks the "mirror" link. cfg['mirror-link-preload'] = 'Template:Documentation/mirror' ---------------------------------------------------------------------------------------------------- -- Test cases link configuration ---------------------------------------------------------------------------------------------------- -- cfg['testcases-subpage'] -- The name of the template subpage typically used for test cases. cfg['testcases-subpage'] = 'หน้าทดสอบ' -- cfg['template-testcases-preload'] -- Preload file for template test cases pages. cfg['template-testcases-preload'] = 'Template:Documentation/preload-testcases' -- cfg['module-testcases-preload'] -- Preload file for Lua module test cases pages. cfg['module-testcases-preload'] = 'Template:Documentation/preload-module-testcases' -- cfg['testcases-link-display'] -- The text to display for "testcases" links. cfg['testcases-link-display'] = 'testcases' -- cfg['testcases-edit-link-display'] -- The text to display for test cases "edit" links. cfg['testcases-edit-link-display'] = 'แก้ไข' -- cfg['testcases-run-link-display'] -- The text to display for test cases "run" links. cfg['testcases-run-link-display'] = 'run' -- cfg['testcases-create-link-display'] -- The text to display for test cases "create" links. cfg['testcases-create-link-display'] = 'สร้าง' ---------------------------------------------------------------------------------------------------- -- Add categories blurb configuration ---------------------------------------------------------------------------------------------------- --[[ -- cfg['add-categories-blurb'] -- Text to direct users to add categories to the /doc subpage. Not used if the "content" or -- "docname fed" arguments are set, as then it is not clear where to add the categories. $1 is a -- link to the /doc subpage with a display value of cfg['doc-link-display']. --]] cfg['add-categories-blurb'] = 'Add categories to the $1 subpage.' -- cfg['doc-link-display'] -- The text to display when linking to the /doc subpage. cfg['doc-link-display'] = '/doc' ---------------------------------------------------------------------------------------------------- -- Subpages link configuration ---------------------------------------------------------------------------------------------------- --[[ -- cfg['subpages-blurb'] -- The "Subpages of this template" blurb. $1 is a link to the main template's subpages with a -- display value of cfg['subpages-link-display']. In the English version this blurb is simply -- the link followed by a period, and the link display provides the actual text. --]] cfg['subpages-blurb'] = '$1.' --[[ -- cfg['subpages-link-display'] -- The text to display for the "subpages of this page" link. $1 is cfg['template-pagetype'], -- cfg['module-pagetype'] or cfg['default-pagetype'], depending on whether the current page is in -- the template namespace, the module namespace, or another namespace. --]] cfg['subpages-link-display'] = 'Subpages of this $1' -- cfg['template-pagetype'] -- The pagetype to display for template pages. cfg['template-pagetype'] = 'แม่แบบ' -- cfg['module-pagetype'] -- The pagetype to display for Lua module pages. cfg['module-pagetype'] = 'มอดูล' -- cfg['default-pagetype'] -- The pagetype to display for pages other than templates or Lua modules. cfg['default-pagetype'] = 'หนัา' ---------------------------------------------------------------------------------------------------- -- Doc link configuration ---------------------------------------------------------------------------------------------------- -- cfg['doc-subpage'] -- The name of the subpage typically used for documentation pages. cfg['doc-subpage'] = 'doc' -- cfg['docpage-preload'] -- Preload file for template documentation pages in all namespaces. cfg['docpage-preload'] = 'Template:Documentation/preload' -- cfg['module-preload'] -- Preload file for Lua module documentation pages. cfg['module-preload'] = 'Template:Documentation/preload-module-doc' ---------------------------------------------------------------------------------------------------- -- HTML and CSS configuration ---------------------------------------------------------------------------------------------------- -- cfg['templatestyles'] -- The name of the TemplateStyles page where CSS is kept. -- Sandbox CSS will be at Module:Documentation/sandbox/styles.css when needed. cfg['templatestyles'] = 'Module:Documentation/styles.css' -- cfg['container'] -- Class which can be used to set flex or grid CSS on the -- two child divs documentation and documentation-metadata cfg['container'] = 'documentation-container' -- cfg['main-div-classes'] -- Classes added to the main HTML "div" tag. cfg['main-div-classes'] = 'documentation' -- cfg['main-div-heading-class'] -- Class for the main heading for templates and modules and assoc. talk spaces cfg['main-div-heading-class'] = 'documentation-heading' -- cfg['start-box-class'] -- Class for the start box cfg['start-box-class'] = 'documentation-startbox' -- cfg['start-box-link-classes'] -- Classes used for the [view][edit][history] or [create] links in the start box. -- mw-editsection-like is per [[Wikipedia:Village pump (technical)/Archive 117]] cfg['start-box-link-classes'] = 'mw-editsection-like plainlinks' -- cfg['end-box-class'] -- Class for the end box. cfg['end-box-class'] = 'documentation-metadata' -- cfg['end-box-plainlinks'] -- Plainlinks cfg['end-box-plainlinks'] = 'plainlinks' -- cfg['toolbar-class'] -- Class added for toolbar links. cfg['toolbar-class'] = 'documentation-toolbar' -- cfg['clear'] -- Just used to clear things. cfg['clear'] = 'documentation-clear' ---------------------------------------------------------------------------------------------------- -- Tracking category configuration ---------------------------------------------------------------------------------------------------- -- cfg['display-strange-usage-category'] -- Set to true to enable output of cfg['strange-usage-category'] if the module is used on a /doc subpage -- or a /testcases subpage. This should be a boolean value (either true or false). cfg['display-strange-usage-category'] = true -- cfg['strange-usage-category'] -- Category to output if cfg['display-strange-usage-category'] is set to true and the module is used on a -- /doc subpage or a /testcases subpage. cfg['strange-usage-category'] = 'Wikipedia pages with strange ((documentation)) usage' --[[ ---------------------------------------------------------------------------------------------------- -- End configuration -- -- Don't edit anything below this line. ---------------------------------------------------------------------------------------------------- --]] return cfg fada130f62abf5df20654808e62ccaf91b673e46 แม่แบบ:Pp-template 10 10 15 2023-10-05T09:21:11Z PeachFullzZ 2 สร้างหน้าด้วย "<includeonly>{{#invoke:Protection banner|main}}</includeonly><noinclude> {{เอกสารประกอบ}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude>" wikitext text/x-wiki <includeonly>{{#invoke:Protection banner|main}}</includeonly><noinclude> {{เอกสารประกอบ}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude> 8e93874248330f5ee5de3f0e1c4db9f3f6ceadd5 แม่แบบ:กล่องข้อมูล ผู้ดำรงตำแหน่ง 10 11 18 2023-10-05T10:08:20Z PeachFullzZ 2 สร้างหน้าด้วย "{{#invoke:infobox|infoboxTemplate | bodyclass = vcard {{{bodyclass|}}} | bodystyle = {{#if:{{{mainwidth|}}}|width: {{{mainwidth}}}}} | child = {{lc:{{{embed}}}}} | abovestyle = font-size: 100%; | above = {{#if:{{{honorific prefix|{{{honorific_prefix|{{{honorific-prefix|}}}}}}}}}|<div class="honorific-prefix" style="font-weight: normal;">{{{honorific prefix|{{{honorific_prefix|{{{honorific-prefix}}}}}}}}}</div>}}<!-- --><div class="fn" style="f..." wikitext text/x-wiki {{#invoke:infobox|infoboxTemplate | bodyclass = vcard {{{bodyclass|}}} | bodystyle = {{#if:{{{mainwidth|}}}|width: {{{mainwidth}}}}} | child = {{lc:{{{embed}}}}} | abovestyle = font-size: 100%; | above = {{#if:{{{honorific prefix|{{{honorific_prefix|{{{honorific-prefix|}}}}}}}}}|<div class="honorific-prefix" style="font-weight: normal;">{{{honorific prefix|{{{honorific_prefix|{{{honorific-prefix}}}}}}}}}</div>}}<!-- --><div class="fn" style="font-size:125%;">{{#if:{{{name|}}}|{{{name}}}|{{PAGENAMEBASE}}}}</div><!-- -->{{#if:{{{honorific suffix|{{{honorific_suffix|{{{honorific-suffix|}}}}}}}}}|<div class="honorific-suffix" style="font-weight: normal;">{{{honorific suffix|{{{honorific_suffix|{{{honorific-suffix}}}}}}}}}</div>}} | subheaderstyle = font-size:125%; font-weight:bold; | subheader = {{#ifeq:{{lc:{{{embed}}}}}|yes||{{#if:{{{native_name|}}}|{{#if:{{{native_name_lang|}}}|<div class="nickname" lang="{{{native_name_lang}}}">}}{{{native_name}}}{{#if:{{{native_name_lang|}}}|</div>}}}}}} | image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{{width|{{{imagesize|{{{image_size|}}}}}}}}}|sizedefault=frameless|upright={{{image_upright|1}}}|alt={{{alt|}}}|suppressplaceholder=yes}} | image2 = {{#invoke:InfoboxImage|InfoboxImage|image={{{image name|}}}|size={{{width|{{{imagesize|{{{image_size|}}}}}}}}}|sizedefault=frameless|upright={{{image_upright|1}}}|alt={{{image_name_alt|}}}|suppressplaceholder=yes}} | image3 = {{#invoke:InfoboxImage|InfoboxImage|image={{{smallimage|}}}|sizedefault=frameless|upright={{{image_upright|1}}}|alt={{{smallimage_alt|}}}|suppressplaceholder=yes}} | captionstyle = line-height:normal;padding-top:0.2em; | caption{{#if:{{{smallimage|}}}|3|{{#if:{{{image name|}}}|2}}}} = {{{caption|}}} | headerstyle = {{#ifeq:{{lc:{{{embed}}}}}|yes|background:#eee|background:lavender}} | data1 = {{#if:{{{speaker|}}}| {{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname2|}}} | 1namedata = {{{1namedata2|}}} | 2blankname = {{{2blankname2|}}} | 2namedata = {{{2namedata2|}}} | 3blankname = {{{3blankname2|}}} | 3namedata = {{{3namedata2|}}} | 4blankname = {{{4blankname2|}}} | 4namedata = {{{4namedata2|}}} | 5blankname = {{{5blankname2|}}} | 5namedata = {{{5namedata2|}}} | alongside = {{{alongside2|}}} | ambassador_from = {{{ambassador_from2|}}} | appointer = {{#if: {{{appointer2|}}} | {{{appointer2}}} | {{{appointed2|}}} }} | assembly = {{{assembly2|}}} | assuming = {{{assuming2|}}} | chancellor = {{{chancellor2|}}} | co-leader = {{{co-leader2|}}} | constituency_{{#if:{{{constituency_AM2|}}}|AM|MP}} = {{#if: {{{constituency_AM2|}}} | {{{constituency_AM2}}} | {{{constituency_MP2|}}} }} | constituency = {{{constituency2|}}} | convocation = {{{convocation2|}}} | country = {{{country2|}}} | deputy = {{{deputy2|}}} | deputyminister = {{{deputyminister2|}}} | headminister = {{{headminister2|}}} | district = {{{district2|}}} | firstminister = {{{firstminister2|}}} | governor-general = {{{governor-general2|}}} | governor_general = {{{governor_general2|}}} | governor = {{{governor2|}}} | jr/sr = {{{jr/sr2|}}} | jr/sr and state = {{{jr/sr and state2|}}} | leader = {{{leader2|}}} | legislature = {{{legislature2|}}} | lieutenant_governor = {{{lieutenant_governor2|}}} | lieutenant = {{{lieutenant2|}}} | majority_leader = {{#if: {{{majorityleader2|}}} | {{{majorityleader2}}} | {{{majority_leader2|}}} }} | minister_from = {{{minister_from2|}}} | minority_floor_leader = {{{minority_floor_leader2|}}} | majority_floor_leader = {{{majority_floor_leader2|}}} | majority = {{{majority2|}}} | minister = {{{minister2|}}} | minority_leader = {{#if: {{{minorityleader2|}}} | {{{minorityleader2}}} | {{{minority_leader2|}}} }} | monarch = {{{monarch2|}}} | nominator = {{{nominator2|}}} | office = {{{office2|}}} | order = {{{order2|}}} | parliament = {{{parliament2|}}} | parliamentarygroup = {{{parliamentarygroup2|}}} | predecessor = {{{predecessor2|}}} | preceding = {{{preceding2|}}} | preceded = {{{preceded2|}}} | premier = {{{premier2|}}} | president = {{{president2|}}} | primeminister = {{{primeminister2|}}} | riding = {{{riding2|}}} | speaker = {{{speaker|}}} | speaker_office = {{{speaker_office|}}} | state_assembly = {{{state_assembly|}}} | state_delegate = {{{state_delegate|}}} | state_house = {{{state_house|}}} | state_legislature = {{{state_legislature|}}} | state_senate = {{{state_senate|}}} | state = {{{state|}}} | subterm = {{{subterm|}}} | suboffice = {{{suboffice|}}} | succeeded = {{{succeeded2|}}} | succeeding = {{{succeeding2|}}} | successor = {{{successor2|}}} | taoiseach = {{{taoiseach2|}}} | termlabel = {{{term_label2|{{{termlabel2|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend2|}}}|{{{termend2}}}|{{{term_end2|}}}}} | termstart = {{#if:{{{termstart2|}}}|{{{termstart2}}}|{{{term_start2|}}}}} | term = {{{term2|}}} | title = {{{title2|}}} | vicegovernor = {{{vicegovernor2|}}} | vicepresident = {{{vicepresident2|}}} | vicepremier = {{{vicepremier2|}}} | viceprimeminister = {{{viceprimeminister2|}}} | party = {{{party|}}} | prior_term = {{{prior_term|}}} }}}}}}<!-- -->{{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname|}}} | 1namedata = {{{1namedata|}}} | 2blankname = {{{2blankname|}}} | 2namedata = {{{2namedata|}}} | 3blankname = {{{3blankname|}}} | 3namedata = {{{3namedata|}}} | 4blankname = {{{4blankname|}}} | 4namedata = {{{4namedata|}}} | 5blankname = {{{5blankname|}}} | 5namedata = {{{5namedata|}}} | alongside = {{{alongside|}}} | ambassador_from = {{{ambassador_from|}}} | appointer = {{#if: {{{appointer|}}} | {{{appointer}}} | {{{appointed|}}} }} | assembly = {{{assembly|}}} | assuming = {{{assuming|}}} | candidate = {{{candidate|}}} | chancellor = {{{chancellor|}}} | co-leader = {{{co-leader|}}} | constituency_{{#if:{{{constituency_AM|}}}|AM|MP}} = {{#if: {{{constituency_AM|}}} | {{{constituency_AM}}} | {{{constituency_MP|}}} }} | constituency = {{{constituency|}}} | convocation = {{{convocation|}}} | country = {{{country|}}} | deputy = {{{deputy|}}} | deputyminister = {{{deputyminister|}}} | headminister = {{{headminister|}}} | district = {{{district|}}} | election_date = {{{election_date|}}} | firstminister = {{{firstminister|}}} | governor-general = {{{governor-general|}}} | governor_general = {{{governor_general|}}} | governor = {{{governor|}}} | incumbent = {{{incumbent|}}} | jr/sr = {{{jr/sr|}}} | jr/sr and state = {{{jr/sr and state|}}} | leader = {{{leader|}}} | legislature = {{{legislature|}}} | lieutenant_governor = {{{lieutenant_governor|}}} | lieutenant = {{{lieutenant|}}} | majority_leader = {{#if: {{{majorityleader|}}} | {{{majorityleader}}} | {{{majority_leader|}}} }} | majority = {{{majority|}}} | minister = {{{minister|}}} | minister_from = {{{minister_from|}}} | minority_floor_leader = {{{minority_floor_leader|}}} | majority_floor_leader = {{{majority_floor_leader|}}} | minority_leader = {{#if: {{{minorityleader|}}} | {{{minorityleader}}} | {{{minority_leader|}}} }} | monarch = {{{monarch|}}} | nominator = {{{nominator|}}} | nominee = {{{nominee|}}} | office = {{{office|}}} | opponent = {{{opponent|}}} | order = {{{order|}}} | parliament = {{{parliament|}}} | parliamentarygroup = {{{parliamentarygroup|}}} | party_election = {{{party_election|}}} | predecessor = {{{predecessor|}}} | preceding = {{{preceding|}}} | preceded = {{{preceded|}}} | premier = {{{premier|}}} | president = {{{president|}}} | primeminister = {{{primeminister|}}} | riding = {{{riding|}}} | runningmate = {{{runningmate|}}} | state_assembly = {{{state_assembly|}}} | state_delegate = {{{state_delegate|}}} | state_house = {{{state_house|}}} | state_legislature = {{{state_legislature|}}} | state_senate = {{{state_senate|}}} | state = {{{state|}}} | status = {{{status|}}} | suboffice = {{{suboffice|}}} | subterm = {{{subterm|}}} | succeeded = {{{succeeded|}}} | succeeding = {{{succeeding|}}} | successor = {{{successor|}}} | taoiseach = {{{taoiseach|}}} | termlabel = {{{term_label|{{{termlabel|ดำรงตำแหน่ง}}}}}} | termend = {{#if: {{{termend|}}} | {{{termend}}} | {{{term_end|}}} }} | termstart = {{#if: {{{termstart|}}} | {{{termstart}}} | {{{term_start|}}} }} | term = {{{term|}}} | title = {{{title|}}} | vicegovernor = {{{vicegovernor|}}} | vicepresident = {{{vicepresident|}}} | vicepremier = {{{vicepremier|}}} | viceprimeminister = {{{viceprimeminister|}}} | party = {{{party|}}} | prior_term = {{{prior_term|}}} }}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname1|}}} | 1namedata = {{{1namedata1|}}} | 2blankname = {{{2blankname1|}}} | 2namedata = {{{2namedata1|}}} | 3blankname = {{{3blankname1|}}} | 3namedata = {{{3namedata1|}}} | 4blankname = {{{4blankname1|}}} | 4namedata = {{{4namedata1|}}} | 5blankname = {{{5blankname1|}}} | 5namedata = {{{5namedata1|}}} | alongside = {{{alongside1|}}} | ambassador_from = {{{ambassador_from1|}}} | appointer = {{#if: {{{appointer1|}}} | {{{appointer1}}} | {{{appointed1|}}} }} | assembly = {{{assembly1|}}} | assuming = {{{assuming1|}}} | chancellor = {{{chancellor1|}}} | co-leader = {{{co-leader1|}}} | constituency_{{#if:{{{constituency_AM1|}}}|AM|MP}} = {{#if: {{{constituency_AM1|}}} | {{{constituency_AM1}}} | {{{constituency_MP1|}}} }} | constituency = {{{constituency1|}}} | convocation = {{{convocation1|}}} | country = {{{country1|}}} | deputy = {{{deputy1|}}} | deputyminister = {{{deputyminister1|}}} | headminister = {{{headminister1|}}} | district = {{{district1|}}} | firstminister = {{{firstminister1|}}} | governor-general = {{{governor-general1|}}} | governor_general = {{{governor_general1|}}} | governor = {{{governor1|}}} | jr/sr = {{{jr/sr1|}}} | jr/sr and state = {{{jr/sr and state1|}}} | leader = {{{leader1|}}} | legislature = {{{legislature1|}}} | lieutenant_governor = {{{lieutenant_governor1|}}} | lieutenant = {{{lieutenant1|}}} | minority_floor_leader = {{{minority_floor_leader1|}}} | minister_from = {{{minister_from1|}}} | majority_floor_leader = {{{majority_floor_leader1|}}} | majority_leader = {{#if: {{{majorityleader1|}}} | {{{majorityleader1}}} | {{{majority_leader1|}}} }} | majority = {{{majority1|}}} | minister = {{{minister1|}}} | minority_leader = {{#if: {{{minorityleader1|}}} | {{{minorityleader1}}} | {{{minority_leader1|}}} }} | monarch = {{{monarch1|}}} | nominator = {{{nominator1|}}} | office = {{{office1|}}} | order = {{{order1|}}} | parliament = {{{parliament1|}}} | parliamentarygroup = {{{parliamentarygroup1|}}} | predecessor = {{{predecessor1|}}} | preceding = {{{preceding1|}}} | preceded = {{{preceded1|}}} | premier = {{{premier1|}}} | president = {{{president1|}}} | primeminister = {{{primeminister1|}}} | riding = {{{riding1|}}} | state_assembly = {{{state_assembly1|}}} | state_delegate = {{{state_delegate1|}}} | state_house = {{{state_house1|}}} | state_legislature = {{{state_legislature1|}}} | state_senate = {{{state_senate1|}}} | state = {{{state1|}}} | status = {{{status1|}}} | subterm = {{{subterm1|}}} | suboffice = {{{suboffice1|}}} | succeeded = {{{succeeded1|}}} | succeeding = {{{succeeding1|}}} | successor = {{{successor1|}}} | taoiseach = {{{taoiseach1|}}} | termlabel = {{{term_label1|{{{termlabel1|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend1|}}}|{{{termend1}}}|{{{term_end1|}}}}} | termstart = {{#if:{{{termstart1|}}}|{{{termstart1}}}|{{{term_start1|}}}}} | term = {{{term1|}}} | title = {{{title1|}}} | vicegovernor = {{{vicegovernor1|}}} | vicepresident = {{{vicepresident1|}}} | vicepremier = {{{vicepremier1|}}} | viceprimeminister = {{{viceprimeminister1|}}} | party = {{{party|}}} | prior_term = {{{prior_term1|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{#if:{{{speaker|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname2|}}} | 1namedata = {{{1namedata2|}}} | 2blankname = {{{2blankname2|}}} | 2namedata = {{{2namedata2|}}} | 3blankname = {{{3blankname2|}}} | 3namedata = {{{3namedata2|}}} | 4blankname = {{{4blankname2|}}} | 4namedata = {{{4namedata2|}}} | 5blankname = {{{5blankname2|}}} | 5namedata = {{{5namedata2|}}} | alongside = {{{alongside2|}}} | ambassador_from = {{{ambassador_from2|}}} | appointer = {{#if: {{{appointer2|}}} | {{{appointer2}}} | {{{appointed2|}}} }} | assembly = {{{assembly2|}}} | assuming = {{{assuming2|}}} | chancellor = {{{chancellor2|}}} | co-leader = {{{co-leader2|}}} | constituency_{{#if:{{{constituency_AM2|}}}|AM|MP}} = {{#if: {{{constituency_AM2|}}} | {{{constituency_AM2}}} | {{{constituency_MP2|}}} }} | constituency = {{{constituency2|}}} | convocation = {{{convocation2|}}} | country = {{{country2|}}} | deputy = {{{deputy2|}}} | deputyminister = {{{deputyminister2|}}} | headminister = {{{headminister2|}}} | district = {{{district2|}}} | firstminister = {{{firstminister2|}}} | governor-general = {{{governor-general2|}}} | governor_general = {{{governor_general2|}}} | governor = {{{governor2|}}} | jr/sr = {{{jr/sr2|}}} | jr/sr and state = {{{jr/sr and state2|}}} | leader = {{{leader2|}}} | legislature = {{{legislature2|}}} | lieutenant_governor = {{{lieutenant_governor2|}}} | lieutenant = {{{lieutenant2|}}} | majority_leader = {{#if: {{{majorityleader2|}}} | {{{majorityleader2}}} | {{{majority_leader2|}}} }} | minister_from = {{{minister_from2|}}} | minority_floor_leader = {{{minority_floor_leader2|}}} | majority_floor_leader = {{{majority_floor_leader2|}}} | majority = {{{majority2|}}} | minister = {{{minister2|}}} | minority_leader = {{#if: {{{minorityleader2|}}} | {{{minorityleader2}}} | {{{minority_leader2|}}} }} | monarch = {{{monarch2|}}} | nominator = {{{nominator2|}}} | office = {{{office2|}}} | order = {{{order2|}}} | parliament = {{{parliament2|}}} | parliamentarygroup = {{{parliamentarygroup2|}}} | predecessor = {{{predecessor2|}}} | preceding = {{{preceding2|}}} | preceded = {{{preceded2|}}} | premier = {{{premier2|}}} | president = {{{president2|}}} | primeminister = {{{primeminister2|}}} | riding = {{{riding2|}}} | state_assembly = {{{state_assembly2|}}} | state_delegate = {{{state_delegate2|}}} | state_house = {{{state_house2|}}} | state_legislature = {{{state_legislature2|}}} | state_senate = {{{state_senate2|}}} | state = {{{state2|}}} | status = {{{status2|}}} | subterm = {{{subterm2|}}} | suboffice = {{{suboffice2|}}} | succeeded = {{{succeeded2|}}} | succeeding = {{{succeeding2|}}} | successor = {{{successor2|}}} | taoiseach = {{{taoiseach2|}}} | termlabel = {{{term_label2|{{{termlabel2|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend2|}}}|{{{termend2}}}|{{{term_end2|}}}}} | termstart = {{#if:{{{termstart2|}}}|{{{termstart2}}}|{{{term_start2|}}}}} | term = {{{term2|}}} | title = {{{title2|}}} | vicegovernor = {{{vicegovernor2|}}} | vicepresident = {{{vicepresident2|}}} | vicepremier = {{{vicepremier2|}}} | viceprimeminister = {{{viceprimeminister2|}}} | party = {{{party|}}} | prior_term = {{{prior_term2|}}} }}}}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname3|}}} | 1namedata = {{{1namedata3|}}} | 2blankname = {{{2blankname3|}}} | 2namedata = {{{2namedata3|}}} | 3blankname = {{{3blankname3|}}} | 3namedata = {{{3namedata3|}}} | 4blankname = {{{4blankname3|}}} | 4namedata = {{{4namedata3|}}} | 5blankname = {{{5blankname3|}}} | 5namedata = {{{5namedata3|}}} | alongside = {{{alongside3|}}} | ambassador_from = {{{ambassador_from3|}}} | appointer = {{#if: {{{appointer3|}}} | {{{appointer3}}} | {{{appointed3|}}} }} | assembly = {{{assembly3|}}} | assuming = {{{assuming3|}}} | chancellor = {{{chancellor3|}}} | co-leader = {{{co-leader3|}}} | constituency_{{#if:{{{constituency_AM3|}}}|AM|MP}} = {{#if: {{{constituency_AM3|}}} | {{{constituency_AM3}}} | {{{constituency_MP3|}}} }} | constituency = {{{constituency3|}}} | convocation = {{{convocation3|}}} | country = {{{country3|}}} | deputy = {{{deputy3|}}} | deputyminister = {{{deputyminister3|}}} | headminister = {{{headminister3|}}} | district = {{{district3|}}} | firstminister = {{{firstminister3|}}} | governor-general = {{{governor-general3|}}} | governor_general = {{{governor_general3|}}} | governor = {{{governor3|}}} | jr/sr = {{{jr/sr3|}}} | jr/sr and state = {{{jr/sr and state3|}}} | leader = {{{leader3|}}} | legislature = {{{legislature3|}}} | lieutenant_governor = {{{lieutenant_governor3|}}} | lieutenant = {{{lieutenant3|}}} | minority_floor_leader = {{{minority_floor_leader3|}}} | minister_from = {{{minister_from3|}}} | majority_floor_leader = {{{majority_floor_leader3|}}} | majority_leader = {{#if: {{{majorityleader3|}}} | {{{majorityleader3}}} | {{{majority_leader3|}}} }} | majority = {{{majority3|}}} | minister = {{{minister3|}}} | minority_leader = {{#if: {{{minorityleader3|}}} | {{{minorityleader3}}} | {{{minority_leader3|}}} }} | monarch = {{{monarch3|}}} | nominator = {{{nominator3|}}} | office = {{{office3|}}} | order = {{{order3|}}} | parliament = {{{parliament3|}}} | parliamentarygroup = {{{parliamentarygroup3|}}} | predecessor = {{{predecessor3|}}} | preceding = {{{preceding3|}}} | preceded = {{{preceded3|}}} | premier = {{{premier3|}}} | president = {{{president3|}}} | primeminister = {{{primeminister3|}}} | riding = {{{riding3|}}} | state_assembly = {{{state_assembly3|}}} | state_delegate = {{{state_delegate3|}}} | state_house = {{{state_house3|}}} | state_legislature = {{{state_legislature3|}}} | state_senate = {{{state_senate3|}}} | state = {{{state3|}}} | status = {{{status3|}}} | subterm = {{{subterm3|}}} | suboffice = {{{suboffice3|}}} | succeeded = {{{succeeded3|}}} | succeeding = {{{succeeding3|}}} | successor = {{{successor3|}}} | taoiseach = {{{taoiseach3|}}} | termlabel = {{{term_label3|{{{termlabel3|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend3|}}}|{{{termend3}}}|{{{term_end3|}}}}} | termstart = {{#if:{{{termstart3|}}}|{{{termstart3}}}|{{{term_start3|}}}}} | term = {{{term3|}}} | title = {{{title3|}}} | vicegovernor = {{{vicegovernor3|}}} | vicepresident = {{{vicepresident3|}}} | vicepremier = {{{vicepremier3|}}} | viceprimeminister = {{{viceprimeminister3|}}} | party = {{{party|}}} | prior_term = {{{prior_term3|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname4|}}} | 1namedata = {{{1namedata4|}}} | 2blankname = {{{2blankname4|}}} | 2namedata = {{{2namedata4|}}} | 3blankname = {{{3blankname4|}}} | 3namedata = {{{3namedata4|}}} | 4blankname = {{{4blankname4|}}} | 4namedata = {{{4namedata4|}}} | 5blankname = {{{5blankname4|}}} | 5namedata = {{{5namedata4|}}} | alongside = {{{alongside4|}}} | ambassador_from = {{{ambassador_from4|}}} | appointer = {{#if: {{{appointer4|}}} | {{{appointer4}}} | {{{appointed4|}}} }} | assembly = {{{assembly4|}}} | assuming = {{{assuming4|}}} | chancellor = {{{chancellor4|}}} | co-leader = {{{co-leader4|}}} | constituency_{{#if:{{{constituency_AM4|}}}|AM|MP}} = {{#if: {{{constituency_AM4|}}} | {{{constituency_AM4}}} | {{{constituency_MP4|}}} }} | constituency = {{{constituency4|}}} | convocation = {{{convocation4|}}} | country = {{{country4|}}} | deputy = {{{deputy4|}}} | deputyminister = {{{deputyminister4|}}} | headminister = {{{headminister4|}}} | district = {{{district4|}}} | firstminister = {{{firstminister4|}}} | governor-general = {{{governor-general4|}}} | governor_general = {{{governor_general4|}}} | governor = {{{governor4|}}} | jr/sr = {{{jr/sr4|}}} | jr/sr and state = {{{jr/sr and state4|}}} | leader = {{{leader4|}}} | legislature = {{{legislature4|}}} | lieutenant_governor = {{{lieutenant_governor4|}}} | lieutenant = {{{lieutenant4|}}} | minister_from = {{{minister_from4|}}} | minority_floor_leader = {{{minority_floor_leader4|}}} | majority_floor_leader = {{{majority_floor_leader4|}}} | majority_leader = {{#if: {{{majorityleader4|}}} | {{{majorityleader4}}} | {{{majority_leader4|}}} }} | majority = {{{majority4|}}} | minister = {{{minister4|}}} | minority_leader = {{#if: {{{minorityleader4|}}} | {{{minorityleader4}}} | {{{minority_leader4|}}} }} | monarch = {{{monarch4|}}} | nominator = {{{nominator4|}}} | office = {{{office4|}}} | order = {{{order4|}}} | parliament = {{{parliament4|}}} | parliamentarygroup = {{{parliamentarygroup4|}}} | predecessor = {{{predecessor4|}}} | preceding = {{{preceding4|}}} | preceded = {{{preceded4|}}} | premier = {{{premier4|}}} | president = {{{president4|}}} | primeminister = {{{primeminister4|}}} | riding = {{{riding4|}}} | state_assembly = {{{state_assembly4|}}} | state_delegate = {{{state_delegate4|}}} | state_house = {{{state_house4|}}} | state_legislature = {{{state_legislature4|}}} | state_senate = {{{state_senate4|}}} | state = {{{state4|}}} | status = {{{status4|}}} | subterm = {{{subterm4|}}} | suboffice = {{{suboffice4|}}} | succeeded = {{{succeeded4|}}} | succeeding = {{{succeeding4|}}} | successor = {{{successor4|}}} | taoiseach = {{{taoiseach4|}}} | termlabel = {{{term_label4|{{{termlabel4|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend4|}}}|{{{termend4}}}|{{{term_end4|}}}}} | termstart = {{#if:{{{termstart4|}}}|{{{termstart4}}}|{{{term_start4|}}}}} | term = {{{term4|}}} | title = {{{title4|}}} | vicegovernor = {{{vicegovernor4|}}} | vicepresident = {{{vicepresident4|}}} | vicepremier = {{{vicepremier4|}}} | viceprimeminister = {{{viceprimeminister4|}}} | party = {{{party|}}} | prior_term = {{{prior_term4|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname5|}}} | 1namedata = {{{1namedata5|}}} | 2blankname = {{{2blankname5|}}} | 2namedata = {{{2namedata5|}}} | 3blankname = {{{3blankname5|}}} | 3namedata = {{{3namedata5|}}} | 4blankname = {{{4blankname5|}}} | 4namedata = {{{4namedata5|}}} | 5blankname = {{{5blankname5|}}} | 5namedata = {{{5namedata5|}}} | alongside = {{{alongside5|}}} | ambassador_from = {{{ambassador_from5|}}} | appointer = {{#if: {{{appointer5|}}} | {{{appointer5}}} | {{{appointed5|}}} }} | assembly = {{{assembly5|}}} | assuming = {{{assuming5|}}} | chancellor = {{{chancellor5|}}} | co-leader = {{{co-leader5|}}} | constituency_{{#if:{{{constituency_AM5|}}}|AM|MP}} = {{#if: {{{constituency_AM5|}}} | {{{constituency_AM5}}} | {{{constituency_MP5|}}} }} | constituency = {{{constituency5|}}} | convocation = {{{convocation5|}}} | country = {{{country5|}}} | deputy = {{{deputy5|}}} | deputyminister = {{{deputyminister5|}}} | headminister = {{{headminister5|}}} | district = {{{district5|}}} | firstminister = {{{firstminister5|}}} | governor-general = {{{governor-general5|}}} | governor_general = {{{governor_general5|}}} | governor = {{{governor5|}}} | jr/sr = {{{jr/sr5|}}} | jr/sr and state = {{{jr/sr and state5|}}} | leader = {{{leader5|}}} | legislature = {{{legislature5|}}} | lieutenant_governor = {{{lieutenant_governor5|}}} | lieutenant = {{{lieutenant5|}}} | minister_from = {{{minister_from5|}}} | minority_floor_leader = {{{minority_floor_leader5|}}} | majority_floor_leader = {{{majority_floor_leader5|}}} | majority_leader = {{#if: {{{majorityleader5|}}} | {{{majorityleader5}}} | {{{majority_leader5|}}} }} | majority = {{{majority5|}}} | minister = {{{minister5|}}} | minority_leader = {{#if: {{{minorityleader5|}}} | {{{minorityleader5}}} | {{{minority_leader5|}}} }} | monarch = {{{monarch5|}}} | nominator = {{{nominator5|}}} | office = {{{office5|}}} | order = {{{order5|}}} | parliament = {{{parliament5|}}} | parliamentarygroup = {{{parliamentarygroup5|}}} | predecessor = {{{predecessor5|}}} | preceding = {{{preceding5|}}} | preceded = {{{preceded5|}}} | premier = {{{premier5|}}} | president = {{{president5|}}} | primeminister = {{{primeminister5|}}} | riding = {{{riding5|}}} | state_assembly = {{{state_assembly5|}}} | state_delegate = {{{state_delegate5|}}} | state_house = {{{state_house5|}}} | state_legislature = {{{state_legislature5|}}} | state_senate = {{{state_senate5|}}} | state = {{{state5|}}} | status = {{{status5|}}} | subterm = {{{subterm5|}}} | suboffice = {{{suboffice5|}}} | succeeded = {{{succeeded5|}}} | succeeding = {{{succeeding5|}}} | successor = {{{successor5|}}} | taoiseach = {{{taoiseach5|}}} | termlabel = {{{term_label5|{{{termlabel5|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend5|}}}|{{{termend5}}}|{{{term_end5|}}}}} | termstart = {{#if:{{{termstart5|}}}|{{{termstart5}}}|{{{term_start5|}}}}} | term = {{{term5|}}} | title = {{{title5|}}} | vicegovernor = {{{vicegovernor5|}}} | vicepresident = {{{vicepresident5|}}} | vicepremier = {{{vicepremier5|}}} | viceprimeminister = {{{viceprimeminister5|}}} | party = {{{party|}}} | prior_term = {{{prior_term5|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname6|}}} | 1namedata = {{{1namedata6|}}} | 2blankname = {{{2blankname6|}}} | 2namedata = {{{2namedata6|}}} | 3blankname = {{{3blankname6|}}} | 3namedata = {{{3namedata6|}}} | 4blankname = {{{4blankname6|}}} | 4namedata = {{{4namedata6|}}} | 5blankname = {{{5blankname6|}}} | 5namedata = {{{5namedata6|}}} | alongside = {{{alongside6|}}} | ambassador_from = {{{ambassador_from6|}}} | appointer = {{#if: {{{appointer6|}}} | {{{appointer6}}} | {{{appointed6|}}} }} | assembly = {{{assembly6|}}} | assuming = {{{assuming6|}}} | chancellor = {{{chancellor6|}}} | co-leader = {{{co-leader6|}}} | constituency_{{#if:{{{constituency_AM6|}}}|AM|MP}} = {{#if: {{{constituency_AM6|}}} | {{{constituency_AM6}}} | {{{constituency_MP6|}}} }} | constituency = {{{constituency6|}}} | convocation = {{{convocation6|}}} | country = {{{country6|}}} | deputy = {{{deputy6|}}} | deputyminister = {{{deputyminister6|}}} | headminister = {{{headminister6|}}} | district = {{{district6|}}} | firstminister = {{{firstminister6|}}} | governor-general = {{{governor-general6|}}} | governor_general = {{{governor_general6|}}} | governor = {{{governor6|}}} | jr/sr = {{{jr/sr6|}}} | jr/sr and state = {{{jr/sr and state6|}}} | leader = {{{leader6|}}} | legislature = {{{legislature6|}}} | lieutenant_governor = {{{lieutenant_governor6|}}} | lieutenant = {{{lieutenant6|}}} | minority_floor_leader = {{{minority_floor_leader6|}}} | minister_from = {{{minister_from6|}}} | majority_floor_leader = {{{majority_floor_leader6|}}} | majority_leader = {{#if: {{{majorityleader6|}}} | {{{majorityleader6}}} | {{{majority_leader6|}}} }} | majority = {{{majority6|}}} | minister = {{{minister6|}}} | minority_leader = {{#if: {{{minorityleader6|}}} | {{{minorityleader6}}} | {{{minority_leader6|}}} }} | monarch = {{{monarch6|}}} | nominator = {{{nominator6|}}} | office = {{{office6|}}} | order = {{{order6|}}} | parliament = {{{parliament6|}}} | parliamentarygroup = {{{parliamentarygroup6|}}} | predecessor = {{{predecessor6|}}} | preceding = {{{preceding6|}}} | preceded = {{{preceded6|}}} | premier = {{{premier6|}}} | president = {{{president6|}}} | primeminister = {{{primeminister6|}}} | riding = {{{riding6|}}} | state_assembly = {{{state_assembly6|}}} | state_delegate = {{{state_delegate6|}}} | state_house = {{{state_house6|}}} | state_legislature = {{{state_legislature6|}}} | state_senate = {{{state_senate6|}}} | state = {{{state6|}}} | status = {{{status6|}}} | subterm = {{{subterm6|}}} | suboffice = {{{suboffice6|}}} | succeeded = {{{succeeded6|}}} | succeeding = {{{succeeding6|}}} | successor = {{{successor6|}}} | taoiseach = {{{taoiseach6|}}} | termlabel = {{{term_label6|{{{termlabel6|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend6|}}}|{{{termend6}}}|{{{term_end6|}}}}} | termstart = {{#if:{{{termstart6|}}}|{{{termstart6}}}|{{{term_start6|}}}}} | term = {{{term6|}}} | title = {{{title6|}}} | vicegovernor = {{{vicegovernor6|}}} | vicepresident = {{{vicepresident6|}}} | vicepremier = {{{vicepremier6|}}} | viceprimeminister = {{{viceprimeminister6|}}} | party = {{{party|}}} | prior_term = {{{prior_term6|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname7|}}} | 1namedata = {{{1namedata7|}}} | 2blankname = {{{2blankname7|}}} | 2namedata = {{{2namedata7|}}} | 3blankname = {{{3blankname7|}}} | 3namedata = {{{3namedata7|}}} | 4blankname = {{{4blankname7|}}} | 4namedata = {{{4namedata7|}}} | 5blankname = {{{5blankname7|}}} | 5namedata = {{{5namedata7|}}} | alongside = {{{alongside7|}}} | ambassador_from = {{{ambassador_from7|}}} | appointer = {{#if: {{{appointer7|}}} | {{{appointer7}}} | {{{appointed7|}}} }} | assembly = {{{assembly7|}}} | assuming = {{{assuming7|}}} | chancellor = {{{chancellor7|}}} | co-leader = {{{co-leader7|}}} | constituency_{{#if:{{{constituency_AM7|}}}|AM|MP}} = {{#if: {{{constituency_AM7|}}} | {{{constituency_AM7}}} | {{{constituency_MP7|}}} }} | constituency = {{{constituency7|}}} | convocation = {{{convocation7|}}} | country = {{{country7|}}} | deputy = {{{deputy7|}}} | deputyminister = {{{deputyminister7|}}} | headminister = {{{headminister7|}}} | district = {{{district7|}}} | firstminister = {{{firstminister7|}}} | governor-general = {{{governor-general7|}}} | governor_general = {{{governor_general7|}}} | governor = {{{governor7|}}} | jr/sr = {{{jr/sr7|}}} | jr/sr and state = {{{jr/sr and state7|}}} | leader = {{{leader7|}}} | legislature = {{{legislature7|}}} | lieutenant_governor = {{{lieutenant_governor7|}}} | lieutenant = {{{lieutenant7|}}} | minister_from = {{{minister_from7|}}} | minority_floor_leader = {{{minority_floor_leader7|}}} | majority_floor_leader = {{{majority_floor_leader7|}}} | majority_leader = {{#if: {{{majorityleader7|}}} | {{{majorityleader7}}} | {{{majority_leader7|}}} }} | majority = {{{majority7|}}} | minister = {{{minister7|}}} | minority_leader = {{#if: {{{minorityleader7|}}} | {{{minorityleader7}}} | {{{minority_leader7|}}} }} | monarch = {{{monarch7|}}} | nominator = {{{nominator7|}}} | office = {{{office7|}}} | order = {{{order7|}}} | parliament = {{{parliament7|}}} | parliamentarygroup = {{{parliamentarygroup7|}}} | predecessor = {{{predecessor7|}}} | preceding = {{{preceding7|}}} | preceded = {{{preceded7|}}} | premier = {{{premier7|}}} | president = {{{president7|}}} | primeminister = {{{primeminister7|}}} | riding = {{{riding7|}}} | state_assembly = {{{state_assembly7|}}} | state_delegate = {{{state_delegate7|}}} | state_house = {{{state_house7|}}} | state_legislature = {{{state_legislature7|}}} | state_senate = {{{state_senate7|}}} | state = {{{state7|}}} | status = {{{status7|}}} | subterm = {{{subterm7|}}} | suboffice = {{{suboffice7|}}} | succeeded = {{{succeeded7|}}} | succeeding = {{{succeeding7|}}} | successor = {{{successor7|}}} | taoiseach = {{{taoiseach7|}}} | termlabel = {{{term_label7|{{{termlabel7|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend7|}}}|{{{termend7}}}|{{{term_end7|}}}}} | termstart = {{#if:{{{termstart7|}}}|{{{termstart7}}}|{{{term_start7|}}}}} | term = {{{term7|}}} | title = {{{title7|}}} | vicegovernor = {{{vicegovernor7|}}} | vicepresident = {{{vicepresident7|}}} | vicepremier = {{{vicepremier7|}}} | viceprimeminister = {{{viceprimeminister7|}}} | party = {{{party|}}} | prior_term = {{{prior_term7|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname8|}}} | 1namedata = {{{1namedata8|}}} | 2blankname = {{{2blankname8|}}} | 2namedata = {{{2namedata8|}}} | 3blankname = {{{3blankname8|}}} | 3namedata = {{{3namedata8|}}} | 4blankname = {{{4blankname8|}}} | 4namedata = {{{4namedata8|}}} | 5blankname = {{{5blankname8|}}} | 5namedata = {{{5namedata8|}}} | alongside = {{{alongside8|}}} | ambassador_from = {{{ambassador_from8|}}} | appointer = {{#if: {{{appointer8|}}} | {{{appointer8}}} | {{{appointed8|}}} }} | assembly = {{{assembly8|}}} | assuming = {{{assuming8|}}} | chancellor = {{{chancellor8|}}} | co-leader = {{{co-leader8|}}} | constituency_{{#if:{{{constituency_AM8|}}}|AM|MP}} = {{#if: {{{constituency_AM8|}}} | {{{constituency_AM8}}} | {{{constituency_MP8|}}} }} | constituency = {{{constituency8|}}} | convocation = {{{convocation8|}}} | country = {{{country8|}}} | deputy = {{{deputy8|}}} | deputyminister = {{{deputyminister8|}}} | headminister = {{{headminister8|}}} | district = {{{district8|}}} | firstminister = {{{firstminister8|}}} | governor-general = {{{governor-general8|}}} | governor_general = {{{governor_general8|}}} | governor = {{{governor8|}}} | jr/sr = {{{jr/sr8|}}} | jr/sr and state = {{{jr/sr and state8|}}} | leader = {{{leader8|}}} | legislature = {{{legislature8|}}} | lieutenant_governor = {{{lieutenant_governor8|}}} | lieutenant = {{{lieutenant8|}}} | minister_from = {{{minister_from8|}}} | minority_floor_leader = {{{minority_floor_leader8|}}} | majority_floor_leader = {{{majority_floor_leader8|}}} | majority_leader = {{#if: {{{majorityleader8|}}} | {{{majorityleader8}}} | {{{majority_leader8|}}} }} | majority = {{{majority8|}}} | minister = {{{minister8|}}} | minority_leader = {{#if: {{{minorityleader8|}}} | {{{minorityleader8}}} | {{{minority_leader8|}}} }} | monarch = {{{monarch8|}}} | nominator = {{{nominator8|}}} | office = {{{office8|}}} | order = {{{order8|}}} | parliament = {{{parliament8|}}} | parliamentarygroup = {{{parliamentarygroup8|}}} | predecessor = {{{predecessor8|}}} | preceding = {{{preceding8|}}} | preceded = {{{preceded8|}}} | premier = {{{premier8|}}} | president = {{{president8|}}} | primeminister = {{{primeminister8|}}} | riding = {{{riding8|}}} | state_assembly = {{{state_assembly8|}}} | state_delegate = {{{state_delegate8|}}} | state_house = {{{state_house8|}}} | state_legislature = {{{state_legislature8|}}} | state_senate = {{{state_senate8|}}} | state = {{{state8|}}} | status = {{{status8|}}} | subterm = {{{subterm8|}}} | suboffice = {{{suboffice8|}}} | succeeded = {{{succeeded8|}}} | succeeding = {{{succeeding8|}}} | successor = {{{successor8|}}} | taoiseach = {{{taoiseach8|}}} | termlabel = {{{term_label8|{{{termlabel8|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend8|}}}|{{{termend8}}}|{{{term_end8|}}}}} | termstart = {{#if:{{{termstart8|}}}|{{{termstart8}}}|{{{term_start8|}}}}} | term = {{{term8|}}} | title = {{{title8|}}} | vicegovernor = {{{vicegovernor8|}}} | vicepresident = {{{vicepresident8|}}} | vicepremier = {{{vicepremier8|}}} | viceprimeminister = {{{viceprimeminister8|}}} | party = {{{party|}}} | prior_term = {{{prior_term8|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname9|}}} | 1namedata = {{{1namedata9|}}} | 2blankname = {{{2blankname9|}}} | 2namedata = {{{2namedata9|}}} | 3blankname = {{{3blankname9|}}} | 3namedata = {{{3namedata9|}}} | 4blankname = {{{4blankname9|}}} | 4namedata = {{{4namedata9|}}} | 5blankname = {{{5blankname9|}}} | 5namedata = {{{5namedata9|}}} | alongside = {{{alongside9|}}} | ambassador_from = {{{ambassador_from9|}}} | appointer = {{#if: {{{appointer9|}}} | {{{appointer9}}} | {{{appointed9|}}} }} | assembly = {{{assembly9|}}} | assuming = {{{assuming9|}}} | chancellor = {{{chancellor9|}}} | co-leader = {{{co-leader9|}}} | constituency_{{#if:{{{constituency_AM9|}}}|AM|MP}} = {{#if: {{{constituency_AM9|}}} | {{{constituency_AM9}}} | {{{constituency_MP9|}}} }} | constituency = {{{constituency9|}}} | convocation = {{{convocation9|}}} | country = {{{country9|}}} | deputy = {{{deputy9|}}} | deputyminister = {{{deputyminister9|}}} | headminister = {{{headminister9|}}} | district = {{{district9|}}} | firstminister = {{{firstminister9|}}} | governor-general = {{{governor-general9|}}} | governor_general = {{{governor_general9|}}} | governor = {{{governor9|}}} | jr/sr = {{{jr/sr9|}}} | jr/sr and state = {{{jr/sr and state9|}}} | leader = {{{leader9|}}} | legislature = {{{legislature9|}}} | lieutenant_governor = {{{lieutenant_governor9|}}} | lieutenant = {{{lieutenant9|}}} | minister_from = {{{minister_from9|}}} | minority_floor_leader = {{{minority_floor_leader9|}}} | majority_floor_leader = {{{majority_floor_leader9|}}} | majority_leader = {{#if: {{{majorityleader9|}}} | {{{majorityleader9}}} | {{{majority_leader9|}}} }} | majority = {{{majority9|}}} | minister = {{{minister9|}}} | minority_leader = {{#if: {{{minorityleader9|}}} | {{{minorityleader9}}} | {{{minority_leader9|}}} }} | monarch = {{{monarch9|}}} | nominator = {{{nominator9|}}} | office = {{{office9|}}} | order = {{{order9|}}} | parliament = {{{parliament9|}}} | parliamentarygroup = {{{parliamentarygroup9|}}} | predecessor = {{{predecessor9|}}} | preceding = {{{preceding9|}}} | preceded = {{{preceded9|}}} | premier = {{{premier9|}}} | president = {{{president9|}}} | primeminister = {{{primeminister9|}}} | riding = {{{riding9|}}} | state_assembly = {{{state_assembly9|}}} | state_delegate = {{{state_delegate9|}}} | state_house = {{{state_house9|}}} | state_legislature = {{{state_legislature9|}}} | state_senate = {{{state_senate9|}}} | state = {{{state9|}}} | status = {{{status9|}}} | subterm = {{{subterm9|}}} | suboffice = {{{suboffice9|}}} | succeeded = {{{succeeded9|}}} | succeeding = {{{succeeding9|}}} | successor = {{{successor9|}}} | taoiseach = {{{taoiseach9|}}} | termlabel = {{{term_label9|{{{termlabel9|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend9|}}}|{{{termend9}}}|{{{term_end9|}}}}} | termstart = {{#if:{{{termstart9|}}}|{{{termstart9}}}|{{{term_start9|}}}}} | term = {{{term9|}}} | title = {{{title9|}}} | vicegovernor = {{{vicegovernor9|}}} | vicepresident = {{{vicepresident9|}}} | vicepremier = {{{vicepremier9|}}} | viceprimeminister = {{{viceprimeminister9|}}} | party = {{{party|}}} | prior_term = {{{prior_term9|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname10|}}} | 1namedata = {{{1namedata10|}}} | 2blankname = {{{2blankname10|}}} | 2namedata = {{{2namedata10|}}} | 3blankname = {{{3blankname10|}}} | 3namedata = {{{3namedata10|}}} | 4blankname = {{{4blankname10|}}} | 4namedata = {{{4namedata10|}}} | 5blankname = {{{5blankname10|}}} | 5namedata = {{{5namedata10|}}} | alongside = {{{alongside10|}}} | ambassador_from = {{{ambassador_from10|}}} | appointer = {{#if: {{{appointer10|}}} | {{{appointer10}}} | {{{appointed10|}}} }} | assembly = {{{assembly10|}}} | assuming = {{{assuming10|}}} | chancellor = {{{chancellor10|}}} | co-leader = {{{co-leader10|}}} | constituency_{{#if:{{{constituency_AM10|}}}|AM|MP}} = {{#if: {{{constituency_AM10|}}} | {{{constituency_AM10}}} | {{{constituency_MP10|}}} }} | constituency = {{{constituency10|}}} | convocation = {{{convocation10|}}} | country = {{{country10|}}} | deputy = {{{deputy10|}}} | deputyminister = {{{deputyminister10|}}} | headminister = {{{headminister10|}}} | district = {{{district10|}}} | firstminister = {{{firstminister10|}}} | governor-general = {{{governor-general10|}}} | governor_general = {{{governor_general10|}}} | governor = {{{governor10|}}} | jr/sr = {{{jr/sr10|}}} | jr/sr and state = {{{jr/sr and state10|}}} | leader = {{{leader10|}}} | legislature = {{{legislature10|}}} | lieutenant_governor = {{{lieutenant_governor10|}}} | lieutenant = {{{lieutenant10|}}} | minister_from = {{{minister_from10|}}} | minority_floor_leader = {{{minority_floor_leader10|}}} | majority_floor_leader = {{{majority_floor_leader10|}}} | majority_leader = {{#if: {{{majorityleader10|}}} | {{{majorityleader10}}} | {{{majority_leader10|}}} }} | majority = {{{majority10|}}} | minister = {{{minister10|}}} | minority_leader = {{#if: {{{minorityleader10|}}} | {{{minorityleader10}}} | {{{minority_leader10|}}} }} | monarch = {{{monarch10|}}} | nominator = {{{nominator10|}}} | office = {{{office10|}}} | order = {{{order10|}}} | parliament = {{{parliament10|}}} | parliamentarygroup = {{{parliamentarygroup10|}}} | predecessor = {{{predecessor10|}}} | preceding = {{{preceding10|}}} | preceded = {{{preceded10|}}} | premier = {{{premier10|}}} | president = {{{president10|}}} | primeminister = {{{primeminister10|}}} | riding = {{{riding10|}}} | state_assembly = {{{state_assembly10|}}} | state_delegate = {{{state_delegate10|}}} | state_house = {{{state_house10|}}} | state_legislature = {{{state_legislature10|}}} | state_senate = {{{state_senate10|}}} | state = {{{state10|}}} | status = {{{status10|}}} | subterm = {{{subterm10|}}} | suboffice = {{{suboffice10|}}} | succeeded = {{{succeeded10|}}} | succeeding = {{{succeeding10|}}} | successor = {{{successor10|}}} | taoiseach = {{{taoiseach10|}}} | termlabel = {{{term_label10|{{{termlabel10|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend10|}}}|{{{termend10}}}|{{{term_end10|}}}}} | termstart = {{#if:{{{termstart10|}}}|{{{termstart10}}}|{{{term_start10|}}}}} | term = {{{term10|}}} | title = {{{title10|}}} | vicegovernor = {{{vicegovernor10|}}} | vicepresident = {{{vicepresident10|}}} | vicepremier = {{{vicepremier10|}}} | viceprimeminister = {{{viceprimeminister10|}}} | party = {{{party|}}} | prior_term = {{{prior_term10|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname11|}}} | 1namedata = {{{1namedata11|}}} | 2blankname = {{{2blankname11|}}} | 2namedata = {{{2namedata11|}}} | 3blankname = {{{3blankname11|}}} | 3namedata = {{{3namedata11|}}} | 4blankname = {{{4blankname11|}}} | 4namedata = {{{4namedata11|}}} | 5blankname = {{{5blankname11|}}} | 5namedata = {{{5namedata11|}}} | alongside = {{{alongside11|}}} | ambassador_from = {{{ambassador_from11|}}} | appointer = {{#if: {{{appointer11|}}} | {{{appointer11}}} | {{{appointed11|}}} }} | assembly = {{{assembly11|}}} | assuming = {{{assuming11|}}} | chancellor = {{{chancellor11|}}} | co-leader = {{{co-leader11|}}} | constituency_{{#if:{{{constituency_AM11|}}}|AM|MP}} = {{#if: {{{constituency_AM11|}}} | {{{constituency_AM11}}} | {{{constituency_MP11|}}} }} | constituency = {{{constituency11|}}} | convocation = {{{convocation11|}}} | country = {{{country11|}}} | deputy = {{{deputy11|}}} | deputyminister = {{{deputyminister11|}}} | headminister = {{{headminister11|}}} | district = {{{district11|}}} | firstminister = {{{firstminister11|}}} | governor-general = {{{governor-general11|}}} | governor_general = {{{governor_general11|}}} | governor = {{{governor11|}}} | jr/sr = {{{jr/sr11|}}} | jr/sr and state = {{{jr/sr and state11|}}} | leader = {{{leader11|}}} | legislature = {{{legislature11|}}} | lieutenant_governor = {{{lieutenant_governor11|}}} | lieutenant = {{{lieutenant11|}}} | minister_from = {{{minister_from11|}}} | minority_floor_leader = {{{minority_floor_leader11|}}} | majority_floor_leader = {{{majority_floor_leader11|}}} | majority_leader = {{#if: {{{majorityleader11|}}} | {{{majorityleader11}}} | {{{majority_leader11|}}} }} | majority = {{{majority11|}}} | minister = {{{minister11|}}} | minority_leader = {{#if: {{{minorityleader11|}}} | {{{minorityleader11}}} | {{{minority_leader11|}}} }} | monarch = {{{monarch11|}}} | nominator = {{{nominator11|}}} | office = {{{office11|}}} | order = {{{order11|}}} | parliament = {{{parliament11|}}} | parliamentarygroup = {{{parliamentarygroup11|}}} | predecessor = {{{predecessor11|}}} | preceding = {{{preceding11|}}} | preceded = {{{preceded11|}}} | premier = {{{premier11|}}} | president = {{{president11|}}} | primeminister = {{{primeminister11|}}} | riding = {{{riding11|}}} | state_assembly = {{{state_assembly11|}}} | state_delegate = {{{state_delegate11|}}} | state_house = {{{state_house11|}}} | state_legislature = {{{state_legislature11|}}} | state_senate = {{{state_senate11|}}} | state = {{{state11|}}} | status = {{{status11|}}} | subterm = {{{subterm11|}}} | suboffice = {{{suboffice11|}}} | succeeded = {{{succeeded11|}}} | succeeding = {{{succeeding11|}}} | successor = {{{successor11|}}} | taoiseach = {{{taoiseach11|}}} | termlabel = {{{term_label11|{{{termlabel11|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend11|}}}|{{{termend11}}}|{{{term_end11|}}}}} | termstart = {{#if:{{{termstart11|}}}|{{{termstart11}}}|{{{term_start11|}}}}} | term = {{{term11|}}} | title = {{{title11|}}} | vicegovernor = {{{vicegovernor11|}}} | vicepresident = {{{vicepresident11|}}} | vicepremier = {{{vicepremier11|}}} | viceprimeminister = {{{viceprimeminister11|}}} | party = {{{party|}}} | prior_term = {{{prior_term11|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname12|}}} | 1namedata = {{{1namedata12|}}} | 2blankname = {{{2blankname12|}}} | 2namedata = {{{2namedata12|}}} | 3blankname = {{{3blankname12|}}} | 3namedata = {{{3namedata12|}}} | 4blankname = {{{4blankname12|}}} | 4namedata = {{{4namedata12|}}} | 5blankname = {{{5blankname12|}}} | 5namedata = {{{5namedata12|}}} | alongside = {{{alongside12|}}} | ambassador_from = {{{ambassador_from12|}}} | appointer = {{#if: {{{appointer12|}}} | {{{appointer12}}} | {{{appointed12|}}} }} | assembly = {{{assembly12|}}} | assuming = {{{assuming12|}}} | chancellor = {{{chancellor12|}}} | co-leader = {{{co-leader12|}}} | constituency_{{#if:{{{constituency_AM12|}}}|AM|MP}} = {{#if: {{{constituency_AM12|}}} | {{{constituency_AM12}}} | {{{constituency_MP12|}}} }} | constituency = {{{constituency12|}}} | convocation = {{{convocation12|}}} | country = {{{country12|}}} | deputy = {{{deputy12|}}} | deputyminister = {{{deputyminister12|}}} | headminister = {{{headminister12|}}} | district = {{{district12|}}} | firstminister = {{{firstminister12|}}} | governor-general = {{{governor-general12|}}} | governor_general = {{{governor_general12|}}} | governor = {{{governor12|}}} | jr/sr = {{{jr/sr12|}}} | jr/sr and state = {{{jr/sr and state12|}}} | leader = {{{leader12|}}} | legislature = {{{legislature12|}}} | lieutenant_governor = {{{lieutenant_governor12|}}} | lieutenant = {{{lieutenant12|}}} | minister_from = {{{minister_from12|}}} | minority_floor_leader = {{{minority_floor_leader12|}}} | majority_floor_leader = {{{majority_floor_leader12|}}} | majority_leader = {{#if: {{{majorityleader12|}}} | {{{majorityleader12}}} | {{{majority_leader12|}}} }} | majority = {{{majority12|}}} | minister = {{{minister12|}}} | minority_leader = {{#if: {{{minorityleader12|}}} | {{{minorityleader12}}} | {{{minority_leader12|}}} }} | monarch = {{{monarch12|}}} | nominator = {{{nominator12|}}} | office = {{{office12|}}} | order = {{{order12|}}} | parliament = {{{parliament12|}}} | parliamentarygroup = {{{parliamentarygroup12|}}} | predecessor = {{{predecessor12|}}} | preceding = {{{preceding12|}}} | preceded = {{{preceded12|}}} | premier = {{{premier12|}}} | president = {{{president12|}}} | primeminister = {{{primeminister12|}}} | riding = {{{riding12|}}} | state_assembly = {{{state_assembly12|}}} | state_delegate = {{{state_delegate12|}}} | state_house = {{{state_house12|}}} | state_legislature = {{{state_legislature12|}}} | state_senate = {{{state_senate12|}}} | state = {{{state12|}}} | status = {{{status12|}}} | subterm = {{{subterm12|}}} | suboffice = {{{suboffice12|}}} | succeeded = {{{succeeded12|}}} | succeeding = {{{succeeding12|}}} | successor = {{{successor12|}}} | taoiseach = {{{taoiseach12|}}} | termlabel = {{{term_label12|{{{termlabel12|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend12|}}}|{{{termend12}}}|{{{term_end12|}}}}} | termstart = {{#if:{{{termstart12|}}}|{{{termstart12}}}|{{{term_start12|}}}}} | term = {{{term12|}}} | title = {{{title12|}}} | vicegovernor = {{{vicegovernor12|}}} | vicepresident = {{{vicepresident12|}}} | vicepremier = {{{vicepremier12|}}} | viceprimeminister = {{{viceprimeminister12|}}} | party = {{{party|}}} | prior_term = {{{prior_term12|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname13|}}} | 1namedata = {{{1namedata13|}}} | 2blankname = {{{2blankname13|}}} | 2namedata = {{{2namedata13|}}} | 3blankname = {{{3blankname13|}}} | 3namedata = {{{3namedata13|}}} | 4blankname = {{{4blankname13|}}} | 4namedata = {{{4namedata13|}}} | 5blankname = {{{5blankname13|}}} | 5namedata = {{{5namedata13|}}} | alongside = {{{alongside13|}}} | ambassador_from = {{{ambassador_from13|}}} | appointer = {{#if: {{{appointer13|}}} | {{{appointer13}}} | {{{appointed13|}}} }} | assembly = {{{assembly13|}}} | assuming = {{{assuming13|}}} | chancellor = {{{chancellor13|}}} | co-leader = {{{co-leader13|}}} | constituency_{{#if:{{{constituency_AM13|}}}|AM|MP}} = {{#if: {{{constituency_AM13|}}} | {{{constituency_AM13}}} | {{{constituency_MP13|}}} }} | constituency = {{{constituency13|}}} | convocation = {{{convocation13|}}} | country = {{{country13|}}} | deputy = {{{deputy13|}}} | deputyminister = {{{deputyminister13|}}} | headminister = {{{headminister13|}}} | district = {{{district13|}}} | firstminister = {{{firstminister13|}}} | governor-general = {{{governor-general13|}}} | governor_general = {{{governor_general13|}}} | governor = {{{governor13|}}} | jr/sr = {{{jr/sr13|}}} | jr/sr and state = {{{jr/sr and state13|}}} | leader = {{{leader13|}}} | legislature = {{{legislature13|}}} | lieutenant_governor = {{{lieutenant_governor13|}}} | lieutenant = {{{lieutenant13|}}} | minister_from = {{{minister_from13|}}} | minority_floor_leader = {{{minority_floor_leader13|}}} | majority_floor_leader = {{{majority_floor_leader13|}}} | majority_leader = {{#if: {{{majorityleader13|}}} | {{{majorityleader13}}} | {{{majority_leader13|}}} }} | majority = {{{majority13|}}} | minister = {{{minister13|}}} | minority_leader = {{#if: {{{minorityleader13|}}} | {{{minorityleader13}}} | {{{minority_leader13|}}} }} | monarch = {{{monarch13|}}} | nominator = {{{nominator13|}}} | office = {{{office13|}}} | order = {{{order13|}}} | parliament = {{{parliament13|}}} | parliamentarygroup = {{{parliamentarygroup13|}}} | predecessor = {{{predecessor13|}}} | preceding = {{{preceding13|}}} | preceded = {{{preceded13|}}} | premier = {{{premier13|}}} | president = {{{president13|}}} | primeminister = {{{primeminister13|}}} | riding = {{{riding13|}}} | state_assembly = {{{state_assembly13|}}} | state_delegate = {{{state_delegate13|}}} | state_house = {{{state_house13|}}} | state_legislature = {{{state_legislature13|}}} | state_senate = {{{state_senate13|}}} | state = {{{state13|}}} | status = {{{status13|}}} | subterm = {{{subterm13|}}} | suboffice = {{{suboffice13|}}} | succeeded = {{{succeeded13|}}} | succeeding = {{{succeeding13|}}} | successor = {{{successor13|}}} | taoiseach = {{{taoiseach13|}}} | termlabel = {{{term_label13|{{{termlabel13|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend13|}}}|{{{termend13}}}|{{{term_end13|}}}}} | termstart = {{#if:{{{termstart13|}}}|{{{termstart13}}}|{{{term_start13|}}}}} | term = {{{term13|}}} | title = {{{title13|}}} | vicegovernor = {{{vicegovernor13|}}} | vicepresident = {{{vicepresident13|}}} | vicepremier = {{{vicepremier13|}}} | viceprimeminister = {{{viceprimeminister13|}}} | party = {{{party|}}} | prior_term = {{{prior_term13|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname14|}}} | 1namedata = {{{1namedata14|}}} | 2blankname = {{{2blankname14|}}} | 2namedata = {{{2namedata14|}}} | 3blankname = {{{3blankname14|}}} | 3namedata = {{{3namedata14|}}} | 4blankname = {{{4blankname14|}}} | 4namedata = {{{4namedata14|}}} | 5blankname = {{{5blankname14|}}} | 5namedata = {{{5namedata14|}}} | alongside = {{{alongside14|}}} | ambassador_from = {{{ambassador_from14|}}} | appointer = {{#if: {{{appointer14|}}} | {{{appointer14}}} | {{{appointed14|}}} }} | assembly = {{{assembly14|}}} | assuming = {{{assuming14|}}} | chancellor = {{{chancellor14|}}} | co-leader = {{{co-leader14|}}} | constituency_{{#if:{{{constituency_AM14|}}}|AM|MP}} = {{#if: {{{constituency_AM14|}}} | {{{constituency_AM14}}} | {{{constituency_MP14|}}} }} | constituency = {{{constituency14|}}} | convocation = {{{convocation14|}}} | country = {{{country14|}}} | deputy = {{{deputy14|}}} | deputyminister = {{{deputyminister14|}}} | headminister = {{{headminister14|}}} | district = {{{district14|}}} | firstminister = {{{firstminister14|}}} | governor-general = {{{governor-general14|}}} | governor_general = {{{governor_general14|}}} | governor = {{{governor14|}}} | jr/sr = {{{jr/sr14|}}} | jr/sr and state = {{{jr/sr and state14|}}} | leader = {{{leader14|}}} | legislature = {{{legislature14|}}} | lieutenant_governor = {{{lieutenant_governor14|}}} | lieutenant = {{{lieutenant14|}}} | minister_from = {{{minister_from14|}}} | minority_floor_leader = {{{minority_floor_leader14|}}} | majority_floor_leader = {{{majority_floor_leader14|}}} | majority_leader = {{#if: {{{majorityleader14|}}} | {{{majorityleader14}}} | {{{majority_leader14|}}} }} | majority = {{{majority14|}}} | minister = {{{minister14|}}} | minority_leader = {{#if: {{{minorityleader14|}}} | {{{minorityleader14}}} | {{{minority_leader14|}}} }} | monarch = {{{monarch14|}}} | nominator = {{{nominator14|}}} | office = {{{office14|}}} | order = {{{order14|}}} | parliament = {{{parliament14|}}} | parliamentarygroup = {{{parliamentarygroup14|}}} | predecessor = {{{predecessor14|}}} | preceding = {{{preceding14|}}} | preceded = {{{preceded14|}}} | premier = {{{premier14|}}} | president = {{{president14|}}} | primeminister = {{{primeminister14|}}} | riding = {{{riding14|}}} | state_assembly = {{{state_assembly14|}}} | state_delegate = {{{state_delegate14|}}} | state_house = {{{state_house14|}}} | state_legislature = {{{state_legislature14|}}} | state_senate = {{{state_senate14|}}} | state = {{{state14|}}} | status = {{{status14|}}} | subterm = {{{subterm14|}}} | suboffice = {{{suboffice14|}}} | succeeded = {{{succeeded14|}}} | succeeding = {{{succeeding14|}}} | successor = {{{successor14|}}} | taoiseach = {{{taoiseach14|}}} | termlabel = {{{term_label14|{{{termlabel14|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend14|}}}|{{{termend14}}}|{{{term_end14|}}}}} | termstart = {{#if:{{{termstart14|}}}|{{{termstart14}}}|{{{term_start14|}}}}} | term = {{{term14|}}} | title = {{{title14|}}} | vicegovernor = {{{vicegovernor14|}}} | vicepresident = {{{vicepresident14|}}} | vicepremier = {{{vicepremier14|}}} | viceprimeminister = {{{viceprimeminister14|}}} | party = {{{party|}}} | prior_term = {{{prior_term14|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname15|}}} | 1namedata = {{{1namedata15|}}} | 2blankname = {{{2blankname15|}}} | 2namedata = {{{2namedata15|}}} | 3blankname = {{{3blankname15|}}} | 3namedata = {{{3namedata15|}}} | 4blankname = {{{4blankname15|}}} | 4namedata = {{{4namedata15|}}} | 5blankname = {{{5blankname15|}}} | 5namedata = {{{5namedata15|}}} | alongside = {{{alongside15|}}} | ambassador_from = {{{ambassador_from15|}}} | appointer = {{#if: {{{appointer15|}}} | {{{appointer15}}} | {{{appointed15|}}} }} | assembly = {{{assembly15|}}} | assuming = {{{assuming15|}}} | chancellor = {{{chancellor15|}}} | co-leader = {{{co-leader15|}}} | constituency_{{#if:{{{constituency_AM15|}}}|AM|MP}} = {{#if: {{{constituency_AM15|}}} | {{{constituency_AM15}}} | {{{constituency_MP15|}}} }} | constituency = {{{constituency15|}}} | convocation = {{{convocation15|}}} | country = {{{country15|}}} | deputy = {{{deputy15|}}} | deputyminister = {{{deputyminister15|}}} | headminister = {{{headminister15|}}} | district = {{{district15|}}} | firstminister = {{{firstminister15|}}} | governor-general = {{{governor-general15|}}} | governor_general = {{{governor_general15|}}} | governor = {{{governor15|}}} | jr/sr = {{{jr/sr15|}}} | jr/sr and state = {{{jr/sr and state15|}}} | leader = {{{leader15|}}} | legislature = {{{legislature15|}}} | lieutenant_governor = {{{lieutenant_governor15|}}} | lieutenant = {{{lieutenant15|}}} | minister_from = {{{minister_from15|}}} | minority_floor_leader = {{{minority_floor_leader15|}}} | majority_floor_leader = {{{majority_floor_leader15|}}} | majority_leader = {{#if: {{{majorityleader15|}}} | {{{majorityleader15}}} | {{{majority_leader15|}}} }} | majority = {{{majority15|}}} | minister = {{{minister15|}}} | minority_leader = {{#if: {{{minorityleader15|}}} | {{{minorityleader15}}} | {{{minority_leader15|}}} }} | monarch = {{{monarch15|}}} | nominator = {{{nominator15|}}} | office = {{{office15|}}} | order = {{{order15|}}} | parliament = {{{parliament15|}}} | parliamentarygroup = {{{parliamentarygroup15|}}} | predecessor = {{{predecessor15|}}} | preceding = {{{preceding15|}}} | preceded = {{{preceded15|}}} | premier = {{{premier15|}}} | president = {{{president15|}}} | primeminister = {{{primeminister15|}}} | riding = {{{riding15|}}} | state_assembly = {{{state_assembly15|}}} | state_delegate = {{{state_delegate15|}}} | state_house = {{{state_house15|}}} | state_legislature = {{{state_legislature15|}}} | state_senate = {{{state_senate15|}}} | state = {{{state15|}}} | status = {{{status15|}}} | subterm = {{{subterm15|}}} | suboffice = {{{suboffice15|}}} | succeeded = {{{succeeded15|}}} | succeeding = {{{succeeding15|}}} | successor = {{{successor15|}}} | taoiseach = {{{taoiseach15|}}} | termlabel = {{{term_label15|{{{termlabel15|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend15|}}}|{{{termend15}}}|{{{term_end15|}}}}} | termstart = {{#if:{{{termstart15|}}}|{{{termstart15}}}|{{{term_start15|}}}}} | term = {{{term15|}}} | title = {{{title15|}}} | vicegovernor = {{{vicegovernor15|}}} | vicepresident = {{{vicepresident15|}}} | vicepremier = {{{vicepremier15|}}} | viceprimeminister = {{{viceprimeminister15|}}} | party = {{{party|}}} | prior_term = {{{prior_term15|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname16|}}} | 1namedata = {{{1namedata16|}}} | 2blankname = {{{2blankname16|}}} | 2namedata = {{{2namedata16|}}} | 3blankname = {{{3blankname16|}}} | 3namedata = {{{3namedata16|}}} | 4blankname = {{{4blankname16|}}} | 4namedata = {{{4namedata16|}}} | 5blankname = {{{5blankname16|}}} | 5namedata = {{{5namedata16|}}} | alongside = {{{alongside16|}}} | ambassador_from = {{{ambassador_from16|}}} | appointer = {{#if: {{{appointer16|}}} | {{{appointer16}}} | {{{appointed16|}}} }} | assembly = {{{assembly16|}}} | assuming = {{{assuming16|}}} | chancellor = {{{chancellor16|}}} | co-leader = {{{co-leader16|}}} | constituency_{{#if:{{{constituency_AM16|}}}|AM|MP}} = {{#if: {{{constituency_AM16|}}} | {{{constituency_AM16}}} | {{{constituency_MP16|}}} }} | constituency = {{{constituency16|}}} | convocation = {{{convocation16|}}} | country = {{{country16|}}} | deputy = {{{deputy16|}}} | deputyminister = {{{deputyminister16|}}} | headminister = {{{headminister16|}}} | district = {{{district16|}}} | firstminister = {{{firstminister16|}}} | governor-general = {{{governor-general16|}}} | governor_general = {{{governor_general16|}}} | governor = {{{governor16|}}} | jr/sr = {{{jr/sr16|}}} | jr/sr and state = {{{jr/sr and state16|}}} | leader = {{{leader16|}}} | legislature = {{{legislature16|}}} | lieutenant_governor = {{{lieutenant_governor16|}}} | lieutenant = {{{lieutenant16|}}} | minister_from = {{{minister_from16|}}} | minority_floor_leader = {{{minority_floor_leader16|}}} | majority_floor_leader = {{{majority_floor_leader16|}}} | majority_leader = {{#if: {{{majorityleader16|}}} | {{{majorityleader16}}} | {{{majority_leader16|}}} }} | majority = {{{majority16|}}} | minister = {{{minister16|}}} | minority_leader = {{#if: {{{minorityleader16|}}} | {{{minorityleader16}}} | {{{minority_leader16|}}} }} | monarch = {{{monarch16|}}} | nominator = {{{nominator16|}}} | office = {{{office16|}}} | order = {{{order16|}}} | parliament = {{{parliament16|}}} | parliamentarygroup = {{{parliamentarygroup16|}}} | predecessor = {{{predecessor16|}}} | preceding = {{{preceding16|}}} | preceded = {{{preceded16|}}} | premier = {{{premier16|}}} | president = {{{president16|}}} | primeminister = {{{primeminister16|}}} | riding = {{{riding16|}}} | state_assembly = {{{state_assembly16|}}} | state_delegate = {{{state_delegate16|}}} | state_house = {{{state_house16|}}} | state_legislature = {{{state_legislature16|}}} | state_senate = {{{state_senate16|}}} | state = {{{state16|}}} | status = {{{status16|}}} | subterm = {{{subterm16|}}} | suboffice = {{{suboffice16|}}} | succeeded = {{{succeeded16|}}} | succeeding = {{{succeeding16|}}} | successor = {{{successor16|}}} | taoiseach = {{{taoiseach16|}}} | termlabel = {{{term_label16|{{{termlabel16|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend16|}}}|{{{termend16}}}|{{{term_end16|}}}}} | termstart = {{#if:{{{termstart16|}}}|{{{termstart16}}}|{{{term_start16|}}}}} | term = {{{term16|}}} | title = {{{title16|}}} | vicegovernor = {{{vicegovernor16|}}} | vicepresident = {{{vicepresident16|}}} | vicepremier = {{{vicepremier16|}}} | viceprimeminister = {{{viceprimeminister16|}}} | party = {{{party|}}} | prior_term = {{{prior_term16|}}} }}}} | data2 = {{{module0|}}} <!----------Personal data----------> | header3 = {{#if:{{{pronunciation|}}}{{{birth_name|{{{birthname|}}}}}}{{{birth_date|}}}{{{birth_place|}}}{{{death_date|}}}{{{death_place|}}}{{{resting_place|{{{restingplace|}}}}}}{{{resting_place_coordinates|}}}{{{restingplacecoordinates|}}}{{{burial_place|}}}{{{citizenship|}}}{{{nationality|}}}{{{party|}}}{{{otherparty|}}}{{{spouse|}}}{{{spouses|}}}{{{spouse(s)|}}}{{{partner|}}}{{{relations|}}}{{{children|}}}{{{parents|}}}{{{mother|}}}{{{father|}}}{{{relatives|}}}{{{residence|}}}{{{education|}}}{{{alma_mater|}}}{{{occupation|}}}{{{profession|}}}{{{know for|}}}{{{know_for|}}}{{{known for|}}}{{{known_for|}}}{{{salary|}}}{{{cabinet|}}}{{{committees|}}}{{{portfolio|}}}{{{awards|}}}{{{data1|}}}{{{data2|}}}{{{data3|}}}{{{data4|}}}{{{data5|}}}|ข้อมูลส่วนบุคคล}} | label4 = เสียงอ่าน | data4 = {{{pronunciation|}}} | label5 = เกิด | data5 = {{br separated entries |1 = {{#if:{{{birth_name|{{{birthname|{{{birth name|}}}}}}}}}|<div style="display:inline" class="nickname">{{{birth_name|{{{birthname|{{{birth name}}}}}}}}}</div>}} |2 = {{{birth_date|}}} |3 = {{{birth_place|}}} }} | label6 = เสียชีวิต | data6 = {{br separated entries|{{{death_date|}}}|{{{death_place|}}}}} | label7 = {{#ifexpr: {{strfind short| {{{death_cause|}}}|ถูกลอบสังหาร}} | ลักษณะ |{{#if:{{{death_manner|}}}|ลักษณะ|สาเหตุ}} }}การเสียชีวิต | data7 = {{#if:{{{death_manner|}}}|{{{death_manner|}}}|{{{death_cause|}}}}} | label8 = ที่ไว้ศพ | class8 = label | data8 = {{br separated entries|{{{resting_place|{{{restingplace|{{{burial_place|}}} }}} }}}|{{{resting_place_coordinates|{{{restingplacecoordinates|{{{burial_place|}}} }}} }}}}} | label9 = สัญชาติ | data9 = {{{citizenship|}}} | label10 = เชื้อชาติ | data10 = {{#switch:{{Delink|{{{nationality|}}}}} | {{#ifeq:{{Country2nationality|{{Find country|{{Delink|{{{birth_place|}}}}}}}}}|{{Delink|{{{nationality|}}}}}|{{Delink|{{{nationality|}}}}}}} = | {{#ifeq:{{Find country|{{{birth_place|}}}}}|England|British}} = | #default = {{{nationality|}}} }} | label11 = ศาสนา | data11 = {{{religion|}}} | label12 = พรรคการเมือง | data12 = {{{party|}}} | label13 = {{nowrap|การเข้าร่วม}}<br />{{nowrap|พรรคการเมืองอื่น}} | data13 = {{{otherparty|{{{other_party|}}} }}} | label14 = ความสูง | data14 = {{#if:{{{height|{{{ส่วนสูง|{{{ความสูง|}}} }}} }}}|{{infobox person/height|{{{height|{{{ส่วนสูง|{{{ความสูง|}}} }}} }}}}}}} | label15 = คู่สมรส | data15 = {{{spouse|{{{spouses|{{{spouse(s)|}}}}}}}}} | label16 = คู่อาศัย | data16 = {{{partner|}}} | label17 = ญาติ | data17 = {{{relations|}}} | label18 = บุตร | data18 = {{{children|}}} | label19 = บุพการี | data19 = {{#if:{{{parents|}}}|{{{parents}}}|{{Unbulleted list|{{#if:{{{father|}}}|{{{father}}} (บิดา)}}|{{#if:{{{mother|}}}|{{{mother}}} (มารดา)}}}}}} | label20 = ความสัมพันธ์ | data20 = {{{relatives|}}} | label21 = ที่อยู่อาศัย | class21 = {{#if:{{{death_date|}}}{{{death_place|}}}||label}} | data21 = {{{residence|}}} | label22 = การศึกษา | data22 = {{{education|}}} | label23 = [[โรงเรียนแม่|ศิษย์เก่า]] | data23 = {{{alma_mater|}}} | label24 = อาชีพ | data24= {{{occupation|}}} | label25 = วิชาชีพ | data25 = {{{profession|}}} | label26 = เป็นที่รู้จักจาก | data26 = {{{know for|{{{know_for|{{{known for|{{{known_for|}}} }}} }}} }}} | label27 = เงินเดือน | data27 = {{{salary|}}} | label28 = ทรัพย์สินสุทธิ | data28 = {{{net_worth|}}} | label29 = รัฐบาล | data29 = {{{cabinet|}}} | label30 = คณะกรรมาธิการ | data30 = {{{committees|}}} | label31 = ผลงานเด่น | data31 = {{{portfolio|}}} | label32 = {{#if:{{{mawards|}}}|บำนาญ|รางวัล}} | data32 = {{{awards|}}} | label33 = {{{blank1}}} | data33 = {{{data1|}}} | label34 = {{{blank2}}} | data34 = {{{data2|}}} | label35 = {{{blank3}}} | data35 = {{{data3|}}} | label36 = {{{blank4}}} | data36 = {{{data4|}}} | label37 = {{{blank5}}} | data37 = {{{data5|}}} | label38 = ลายมือชื่อ | data38 = {{#if:{{{signature|}}}|[[File:{{{signature}}}|{{#if:{{{signature_size|}}}|{{{signature_size}}}|128x80px}}|alt={{{signature_alt|}}}|ลายมือชื่อของ{{PAGENAME}}]]}} | label39 = เว็บไซต์ | data39 = {{{website|{{{homepage|}}} }}} | label40 = ชื่อเล่น | data40 = {{{nickname|{{{other_names|{{{othernames|{{{othername|{{{nicknames|}}} }}} }}} }}} }}} | header41 = {{#if:{{{allegiance|}}}{{{branch|}}}{{{serviceyears|}}}{{{rank|}}}{{{unit|}}}{{{commands|}}}{{{battles|}}}{{{wars|}}}{{{battles/wars|}}}{{{military_blank1|}}}|ยศที่ได้รับการแต่งตั้ง}} | label42 = รับใช้ | data42 = {{{allegiance|}}} | label43 = {{#if:{{{branch_label|}}}|{{{branch_label|}}}|สังกัด}} | data43 = {{{branch|}}} | label44 = {{#if:{{{serviceyears_label|}}}|{{{serviceyears_label|}}}|ประจำการ}} | data44 = {{{serviceyears|}}} | label45 = {{#if:{{{rank_label|}}}|{{{rank_label|}}}|ยศ}} | data45 = {{{rank|}}} | label46 = {{#if:{{{unit_label|}}}|{{{unit_label|}}}|หน่วย}} | data46 = {{{unit|}}} | label47 = บังคับบัญชา | data47 = {{{commands|}}} | label48 = {{#if:{{{battles_label|}}}|{{{battles_label|}}}|สงคราม/การสู้รบ}} | data48 = {{{battles|{{{wars|{{{battles/wars|}}} }}} }}} | label49 = {{#if:{{{awards|}}}|บำเหน็จ|รางวัล}} | data49 = {{{mawards|}}} | label50 = {{{military_blank1}}} | data50 = {{{military_data1|}}} | label51 = {{{military_blank2}}} | data51 = {{{military_data2|}}} | label52 = {{{military_blank3}}} | data52 = {{{military_data3|}}} | label53 = {{{military_blank4}}} | data53 = {{{military_data4|}}} | label54 = {{{military_blank5}}} | data54 = {{{military_data5|}}} | data55 = {{{module|}}} | data56 = {{{module2|}}} | data57 = {{{module3|}}} | data58 = {{{module4|}}} | data59 = {{{module5|}}} | data60 = {{{footnotes|}}} | belowstyle = border-top: 1px solid right; font-size: 95% | below = <div>{{#if:{{{date|}}}| ณ วันที่ {{{date}}}{{#if:{{{year|}}}|, {{{year}}}}}}}</div>{{#if:{{{source|}}}|ที่มา: [{{{source}}}]}} }}{{#if:{{{pronunciation|}}}|{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[Category:Biography template using pronunciation]]}} }}{{#if:{{{1blankname0|}}}{{{1namedata0|}}}{{{2blankname0|}}}{{{2namedata0|}}}{{{3blankname0|}}}{{{3namedata0|}}}{{{4blankname0|}}}{{{4namedata0|}}}{{{5blankname0|}}}{{{5namedata0|}}}{{{alongside0|}}}{{{ambassador_from0|}}}{{{appointer0|}}}{{{assembly0|}}}{{{assuming0|}}}{{{chancellor0|}}}{{{co-leader0|}}}{{{constituency_AM0|}}}{{{constituency0|}}}{{{country0|}}}{{{deputy0|}}}{{{district0|}}}{{{firstminister0|}}}{{{governor-general0|}}}{{{governor0|}}}{{{jr/sr0|}}}{{{jr/sr and state0|}}}{{{leader0|}}}{{{legislature0|}}}{{{lieutenant_governor0|}}}{{{lieutenant0|}}}{{{minister_from0|}}}{{{minority_floor_leader0|}}}{{{majority_floor_leader0|}}}{{{majorityleader0|}}}{{{majority0|}}}{{{minister0|}}}{{{minorityleader0|}}}{{{monarch0|}}}{{{nominator0|}}}{{{office0|}}}{{{order0|}}}{{{parliament0|}}}{{{predecessor0|}}}{{{preceding0|}}}{{{preceded0|}}}{{{premier0|}}}{{{president0|}}}{{{primeminister0|}}}{{{riding0|}}}{{{state_assembly0|}}}{{{state_delegate0|}}}{{{state_house0|}}}{{{state_legislature0|}}}{{{state_senate0|}}}{{{state0|}}}{{{suboffice0|}}}{{{subterm0|}}}{{{succeeded0|}}}{{{succeeding0|}}}{{{successor0|}}}{{{taoiseach0|}}}{{{termend0|}}}{{{termstart0|}}}{{{term0|}}}{{{title0|}}}{{{vicegovernor0|}}}{{{vicepresident0|}}}{{{vicepremier0|}}}{{{viceprimeminister0|}}}{{{prior_term0|}}}{{{appointe0|}}}{{{constituency_0|}}}|{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[Category:Pages using infobox officeholder with office0]]}} }}{{#if:{{{speaker|}}}|{{#if:{{{nominee|}}}{{{candidate|}}}||{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[Category:Pages using infobox officeholder with speaker]]}}}} }}{{#invoke:Check for unknown parameters|check|unknown={{main other|{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[หมวดหมู่:หน้าที่ใช้กล่องข้อมูลผู้ดำรงตำแหน่งที่มีพารามิเตอร์ที่ไม่รู้จัก|_VALUE_{{PAGENAME}}]]}}}}|preview=หน้านี้ใช้ [[แม่แบบ:กล่องข้อมูล ผู้ดำรงตำแหน่ง]] ที่มีพารามิเตอร์ที่ไม่รู้จัก "_VALUE_"|ignoreblank=y| regexp1 = 1blankname[%d]* | regexp2 = 1namedata[%d]* | regexp3 = 2blankname[%d]* | regexp4 = 2namedata[%d]* | regexp5 = 3blankname[%d]* | regexp6 = 3namedata[%d]* | regexp7 = 4blankname[%d]* | regexp8 = 4namedata[%d]* | regexp9 = 5blankname[%d]* | regexp10 = 5namedata[%d]* | allegiance | alma_mater | regexp11 = alongside[%d]* | alt | regexp12 = ambassador_from[%d]* | regexp13 = appointed[%d]* | regexp14 = appointer[%d]* | regexp15 = assembly[%d]* | awards | battles | battles/wars | battles_label | birth_date | birth name | birth_name | birth_place | birthname | regexp16 = blank[%d]* | bodyclass | branch | branch_label | burial_place | cabinet | candidate | caption | categories | regexp17 = chancellor[%d]* | children | citizenship | regexp18 = co%-leader[%d]* | commands | committees | regexp19 = constituency[%d]* | regexp20 = constituency_AM[%d]* | regexp21 = constituency_MP[%d]* | regexp22 = convocation[%d]* | regexp23 = country[%d]* | regexp24 = data[%d]* | date | death_cause | death_date | death_manner | death_place | demo | regexp25 = deputy[%d]* | regexp26 = deputyminister[%d]* | regexp27 = district[%d]* | education | election_date | embed | father | regexp28 = firstminister[%d]* | footnotes | regexp29 = governor[%d]* | regexp30 = governor_general[%d]* | regexp31 = governor%-general[%d]* | regexp32 = headminister[%d]* | height | homepage | honorific_prefix | honorific-prefix | honorific_suffix | honorific-suffix | image | image name | image_name_alt | image_size | imagesize | image_upright | incumbent | regexp33 = jr/sr[%d]* | regexp34 = jr/sr and state[%d]* | know for | know_for | known for | known_for | regexp35 = leader[%d]* | regexp36 = legislature[%d]* | regexp37 = lieutenant[%d]* | regexp38 = lieutenant_governor[%d]* | mainwidth | regexp39 = majority[%d]* | regexp40 = majority_floor_leader[%d]* | regexp41 = majority_leader[%d]* | regexp42 = majorityleader[%d]* | mawards | regexp43 = military_blank[%d]* | regexp44 = military_data[%d]* | regexp45 = minister[%d]* | regexp46 = minister_from[%d]* | regexp47 = minority_floor_leader[%d]* | regexp48 = minority_leader[%d]* | regexp49 = minorityleader[%d]* | regexp50 = module[%d]* | regexp51 = monarch[%d]* | mother | name | nationality | native_name | native_name_lang | net_worth | nickname | nicknames | nocat | regexp52 = nominator[%d]* | nominee | occupation | regexp53 = office[%d]* | opponent | regexp54 = order[%d]* | othername | othernames | other_names | otherparty | other_party | parents | regexp55 = parliament[%d]* | regexp56 = parliamentarygroup[%d]* | partner | party | party_election | portfolio | regexp57 = preceded[%d]* | regexp58 = preceding[%d]* | regexp59 = predecessor[%d]* | regexp60 = premier[%d]* | regexp61 = president[%d]* | regexp62 = primeminister[%d]* | regexp63 = prior_term[%d]* | profession | pronunciation | rank | rank_label | relations | relatives | religion | residence | resting_place | resting_place_coordinates | restingplace | restingplacecoordinates | regexp64 = riding[%d]* | runningmate | salary | serviceyears | serviceyears_label | signature | signature_alt | signature_size | smallimage | smallimage_alt | source | speaker | speaker_office | spouse | spouses | spouse(s) | regexp65 = state[%d]* | regexp66 = state_assembly[%d]* | regexp67 = state_delegate[%d]* | regexp68 = state_house[%d]* | regexp69 = state_legislature[%d]* | regexp70 = state_senate[%d]* | regexp71 = status[%d]* | regexp72 = suboffice[%d]* | regexp73 = subterm[%d]* | regexp74 = succeeded[%d]* | regexp75 = succeeding[%d]* | regexp76 = successor[%d]* | regexp77 = taoiseach[%d]* | regexp78 = term[%d]* | regexp79 = term_end[%d]* | regexp80 = term_label[%d]* | regexp81 = term_start[%d]* | regexp82 = termend[%d]* | regexp83 = termlabel[%d]* | regexp84 = termstart[%d]* | regexp85 = title[%d]* | unit | unit_label | regexp86 = vicegovernor[%d]* | regexp87 = vicepremier[%d]* | regexp88 = vicepresident[%d]* | regexp89 = viceprimeminister[%d]* | regexp90 = assuming[%d]* | wars | website | width | year | ความสูง | ส่วนสูง }}<noinclude> {{คู่มือการใช้งาน}} </noinclude> 7c1b0f36986203c98792be636aa1a2fafaab0fef 46 18 2023-10-05T11:34:14Z PeachFullzZ 2 wikitext text/x-wiki {{#invoke:infobox|infoboxTemplate | bodyclass = vcard {{{bodyclass|}}} | bodystyle = {{#if:{{{mainwidth|}}}|width: {{{mainwidth}}}}} | child = {{lc:{{{embed}}}}} | abovestyle = font-size: 100%; | above = {{#if:{{{honorific prefix|{{{honorific_prefix|{{{honorific-prefix|}}}}}}}}}|<div class="honorific-prefix" style="font-weight: normal;">{{{honorific prefix|{{{honorific_prefix|{{{honorific-prefix}}}}}}}}}</div>}}<!-- --><div class="fn" style="font-size:125%;">{{#if:{{{name|}}}|{{{name}}}|{{PAGENAMEBASE}}}}</div><!-- -->{{#if:{{{honorific suffix|{{{honorific_suffix|{{{honorific-suffix|}}}}}}}}}|<div class="honorific-suffix" style="font-weight: normal;">{{{honorific suffix|{{{honorific_suffix|{{{honorific-suffix}}}}}}}}}</div>}} | subheaderstyle = font-size:125%; font-weight:bold; | subheader = {{#ifeq:{{lc:{{{embed}}}}}|yes||{{#if:{{{roblox_username|}}}|{{{roblox_username}}}}}}} | image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{{width|{{{imagesize|{{{image_size|}}}}}}}}}|sizedefault=frameless|upright={{{image_upright|1}}}|alt={{{alt|}}}|suppressplaceholder=yes}} | image2 = {{#invoke:InfoboxImage|InfoboxImage|image={{{image name|}}}|size={{{width|{{{imagesize|{{{image_size|}}}}}}}}}|sizedefault=frameless|upright={{{image_upright|1}}}|alt={{{image_name_alt|}}}|suppressplaceholder=yes}} | image3 = {{#invoke:InfoboxImage|InfoboxImage|image={{{smallimage|}}}|sizedefault=frameless|upright={{{image_upright|1}}}|alt={{{smallimage_alt|}}}|suppressplaceholder=yes}} | captionstyle = line-height:normal;padding-top:0.2em; | caption{{#if:{{{smallimage|}}}|3|{{#if:{{{image name|}}}|2}}}} = {{{caption|}}} | headerstyle = {{#ifeq:{{lc:{{{embed}}}}}|yes|background:#eee|background:lavender}} | data1 = {{#if:{{{speaker|}}}| {{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname2|}}} | 1namedata = {{{1namedata2|}}} | 2blankname = {{{2blankname2|}}} | 2namedata = {{{2namedata2|}}} | 3blankname = {{{3blankname2|}}} | 3namedata = {{{3namedata2|}}} | 4blankname = {{{4blankname2|}}} | 4namedata = {{{4namedata2|}}} | 5blankname = {{{5blankname2|}}} | 5namedata = {{{5namedata2|}}} | alongside = {{{alongside2|}}} | ambassador_from = {{{ambassador_from2|}}} | appointer = {{#if: {{{appointer2|}}} | {{{appointer2}}} | {{{appointed2|}}} }} | assembly = {{{assembly2|}}} | assuming = {{{assuming2|}}} | chancellor = {{{chancellor2|}}} | co-leader = {{{co-leader2|}}} | constituency_{{#if:{{{constituency_AM2|}}}|AM|MP}} = {{#if: {{{constituency_AM2|}}} | {{{constituency_AM2}}} | {{{constituency_MP2|}}} }} | constituency = {{{constituency2|}}} | convocation = {{{convocation2|}}} | country = {{{country2|}}} | deputy = {{{deputy2|}}} | deputyminister = {{{deputyminister2|}}} | headminister = {{{headminister2|}}} | district = {{{district2|}}} | firstminister = {{{firstminister2|}}} | governor-general = {{{governor-general2|}}} | governor_general = {{{governor_general2|}}} | governor = {{{governor2|}}} | jr/sr = {{{jr/sr2|}}} | jr/sr and state = {{{jr/sr and state2|}}} | leader = {{{leader2|}}} | legislature = {{{legislature2|}}} | lieutenant_governor = {{{lieutenant_governor2|}}} | lieutenant = {{{lieutenant2|}}} | majority_leader = {{#if: {{{majorityleader2|}}} | {{{majorityleader2}}} | {{{majority_leader2|}}} }} | minister_from = {{{minister_from2|}}} | minority_floor_leader = {{{minority_floor_leader2|}}} | majority_floor_leader = {{{majority_floor_leader2|}}} | majority = {{{majority2|}}} | minister = {{{minister2|}}} | minority_leader = {{#if: {{{minorityleader2|}}} | {{{minorityleader2}}} | {{{minority_leader2|}}} }} | monarch = {{{monarch2|}}} | nominator = {{{nominator2|}}} | office = {{{office2|}}} | order = {{{order2|}}} | parliament = {{{parliament2|}}} | parliamentarygroup = {{{parliamentarygroup2|}}} | predecessor = {{{predecessor2|}}} | preceding = {{{preceding2|}}} | preceded = {{{preceded2|}}} | premier = {{{premier2|}}} | president = {{{president2|}}} | primeminister = {{{primeminister2|}}} | riding = {{{riding2|}}} | speaker = {{{speaker|}}} | speaker_office = {{{speaker_office|}}} | state_assembly = {{{state_assembly|}}} | state_delegate = {{{state_delegate|}}} | state_house = {{{state_house|}}} | state_legislature = {{{state_legislature|}}} | state_senate = {{{state_senate|}}} | state = {{{state|}}} | subterm = {{{subterm|}}} | suboffice = {{{suboffice|}}} | succeeded = {{{succeeded2|}}} | succeeding = {{{succeeding2|}}} | successor = {{{successor2|}}} | taoiseach = {{{taoiseach2|}}} | termlabel = {{{term_label2|{{{termlabel2|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend2|}}}|{{{termend2}}}|{{{term_end2|}}}}} | termstart = {{#if:{{{termstart2|}}}|{{{termstart2}}}|{{{term_start2|}}}}} | term = {{{term2|}}} | title = {{{title2|}}} | vicegovernor = {{{vicegovernor2|}}} | vicepresident = {{{vicepresident2|}}} | vicepremier = {{{vicepremier2|}}} | viceprimeminister = {{{viceprimeminister2|}}} | party = {{{party|}}} | prior_term = {{{prior_term|}}} }}}}}}<!-- -->{{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname|}}} | 1namedata = {{{1namedata|}}} | 2blankname = {{{2blankname|}}} | 2namedata = {{{2namedata|}}} | 3blankname = {{{3blankname|}}} | 3namedata = {{{3namedata|}}} | 4blankname = {{{4blankname|}}} | 4namedata = {{{4namedata|}}} | 5blankname = {{{5blankname|}}} | 5namedata = {{{5namedata|}}} | alongside = {{{alongside|}}} | ambassador_from = {{{ambassador_from|}}} | appointer = {{#if: {{{appointer|}}} | {{{appointer}}} | {{{appointed|}}} }} | assembly = {{{assembly|}}} | assuming = {{{assuming|}}} | candidate = {{{candidate|}}} | chancellor = {{{chancellor|}}} | co-leader = {{{co-leader|}}} | constituency_{{#if:{{{constituency_AM|}}}|AM|MP}} = {{#if: {{{constituency_AM|}}} | {{{constituency_AM}}} | {{{constituency_MP|}}} }} | constituency = {{{constituency|}}} | convocation = {{{convocation|}}} | country = {{{country|}}} | deputy = {{{deputy|}}} | deputyminister = {{{deputyminister|}}} | headminister = {{{headminister|}}} | district = {{{district|}}} | election_date = {{{election_date|}}} | firstminister = {{{firstminister|}}} | governor-general = {{{governor-general|}}} | governor_general = {{{governor_general|}}} | governor = {{{governor|}}} | incumbent = {{{incumbent|}}} | jr/sr = {{{jr/sr|}}} | jr/sr and state = {{{jr/sr and state|}}} | leader = {{{leader|}}} | legislature = {{{legislature|}}} | lieutenant_governor = {{{lieutenant_governor|}}} | lieutenant = {{{lieutenant|}}} | majority_leader = {{#if: {{{majorityleader|}}} | {{{majorityleader}}} | {{{majority_leader|}}} }} | majority = {{{majority|}}} | minister = {{{minister|}}} | minister_from = {{{minister_from|}}} | minority_floor_leader = {{{minority_floor_leader|}}} | majority_floor_leader = {{{majority_floor_leader|}}} | minority_leader = {{#if: {{{minorityleader|}}} | {{{minorityleader}}} | {{{minority_leader|}}} }} | monarch = {{{monarch|}}} | nominator = {{{nominator|}}} | nominee = {{{nominee|}}} | office = {{{office|}}} | opponent = {{{opponent|}}} | order = {{{order|}}} | parliament = {{{parliament|}}} | parliamentarygroup = {{{parliamentarygroup|}}} | party_election = {{{party_election|}}} | predecessor = {{{predecessor|}}} | preceding = {{{preceding|}}} | preceded = {{{preceded|}}} | premier = {{{premier|}}} | president = {{{president|}}} | primeminister = {{{primeminister|}}} | riding = {{{riding|}}} | runningmate = {{{runningmate|}}} | state_assembly = {{{state_assembly|}}} | state_delegate = {{{state_delegate|}}} | state_house = {{{state_house|}}} | state_legislature = {{{state_legislature|}}} | state_senate = {{{state_senate|}}} | state = {{{state|}}} | status = {{{status|}}} | suboffice = {{{suboffice|}}} | subterm = {{{subterm|}}} | succeeded = {{{succeeded|}}} | succeeding = {{{succeeding|}}} | successor = {{{successor|}}} | taoiseach = {{{taoiseach|}}} | termlabel = {{{term_label|{{{termlabel|ดำรงตำแหน่ง}}}}}} | termend = {{#if: {{{termend|}}} | {{{termend}}} | {{{term_end|}}} }} | termstart = {{#if: {{{termstart|}}} | {{{termstart}}} | {{{term_start|}}} }} | term = {{{term|}}} | title = {{{title|}}} | vicegovernor = {{{vicegovernor|}}} | vicepresident = {{{vicepresident|}}} | vicepremier = {{{vicepremier|}}} | viceprimeminister = {{{viceprimeminister|}}} | party = {{{party|}}} | prior_term = {{{prior_term|}}} }}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname1|}}} | 1namedata = {{{1namedata1|}}} | 2blankname = {{{2blankname1|}}} | 2namedata = {{{2namedata1|}}} | 3blankname = {{{3blankname1|}}} | 3namedata = {{{3namedata1|}}} | 4blankname = {{{4blankname1|}}} | 4namedata = {{{4namedata1|}}} | 5blankname = {{{5blankname1|}}} | 5namedata = {{{5namedata1|}}} | alongside = {{{alongside1|}}} | ambassador_from = {{{ambassador_from1|}}} | appointer = {{#if: {{{appointer1|}}} | {{{appointer1}}} | {{{appointed1|}}} }} | assembly = {{{assembly1|}}} | assuming = {{{assuming1|}}} | chancellor = {{{chancellor1|}}} | co-leader = {{{co-leader1|}}} | constituency_{{#if:{{{constituency_AM1|}}}|AM|MP}} = {{#if: {{{constituency_AM1|}}} | {{{constituency_AM1}}} | {{{constituency_MP1|}}} }} | constituency = {{{constituency1|}}} | convocation = {{{convocation1|}}} | country = {{{country1|}}} | deputy = {{{deputy1|}}} | deputyminister = {{{deputyminister1|}}} | headminister = {{{headminister1|}}} | district = {{{district1|}}} | firstminister = {{{firstminister1|}}} | governor-general = {{{governor-general1|}}} | governor_general = {{{governor_general1|}}} | governor = {{{governor1|}}} | jr/sr = {{{jr/sr1|}}} | jr/sr and state = {{{jr/sr and state1|}}} | leader = {{{leader1|}}} | legislature = {{{legislature1|}}} | lieutenant_governor = {{{lieutenant_governor1|}}} | lieutenant = {{{lieutenant1|}}} | minority_floor_leader = {{{minority_floor_leader1|}}} | minister_from = {{{minister_from1|}}} | majority_floor_leader = {{{majority_floor_leader1|}}} | majority_leader = {{#if: {{{majorityleader1|}}} | {{{majorityleader1}}} | {{{majority_leader1|}}} }} | majority = {{{majority1|}}} | minister = {{{minister1|}}} | minority_leader = {{#if: {{{minorityleader1|}}} | {{{minorityleader1}}} | {{{minority_leader1|}}} }} | monarch = {{{monarch1|}}} | nominator = {{{nominator1|}}} | office = {{{office1|}}} | order = {{{order1|}}} | parliament = {{{parliament1|}}} | parliamentarygroup = {{{parliamentarygroup1|}}} | predecessor = {{{predecessor1|}}} | preceding = {{{preceding1|}}} | preceded = {{{preceded1|}}} | premier = {{{premier1|}}} | president = {{{president1|}}} | primeminister = {{{primeminister1|}}} | riding = {{{riding1|}}} | state_assembly = {{{state_assembly1|}}} | state_delegate = {{{state_delegate1|}}} | state_house = {{{state_house1|}}} | state_legislature = {{{state_legislature1|}}} | state_senate = {{{state_senate1|}}} | state = {{{state1|}}} | status = {{{status1|}}} | subterm = {{{subterm1|}}} | suboffice = {{{suboffice1|}}} | succeeded = {{{succeeded1|}}} | succeeding = {{{succeeding1|}}} | successor = {{{successor1|}}} | taoiseach = {{{taoiseach1|}}} | termlabel = {{{term_label1|{{{termlabel1|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend1|}}}|{{{termend1}}}|{{{term_end1|}}}}} | termstart = {{#if:{{{termstart1|}}}|{{{termstart1}}}|{{{term_start1|}}}}} | term = {{{term1|}}} | title = {{{title1|}}} | vicegovernor = {{{vicegovernor1|}}} | vicepresident = {{{vicepresident1|}}} | vicepremier = {{{vicepremier1|}}} | viceprimeminister = {{{viceprimeminister1|}}} | party = {{{party|}}} | prior_term = {{{prior_term1|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{#if:{{{speaker|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname2|}}} | 1namedata = {{{1namedata2|}}} | 2blankname = {{{2blankname2|}}} | 2namedata = {{{2namedata2|}}} | 3blankname = {{{3blankname2|}}} | 3namedata = {{{3namedata2|}}} | 4blankname = {{{4blankname2|}}} | 4namedata = {{{4namedata2|}}} | 5blankname = {{{5blankname2|}}} | 5namedata = {{{5namedata2|}}} | alongside = {{{alongside2|}}} | ambassador_from = {{{ambassador_from2|}}} | appointer = {{#if: {{{appointer2|}}} | {{{appointer2}}} | {{{appointed2|}}} }} | assembly = {{{assembly2|}}} | assuming = {{{assuming2|}}} | chancellor = {{{chancellor2|}}} | co-leader = {{{co-leader2|}}} | constituency_{{#if:{{{constituency_AM2|}}}|AM|MP}} = {{#if: {{{constituency_AM2|}}} | {{{constituency_AM2}}} | {{{constituency_MP2|}}} }} | constituency = {{{constituency2|}}} | convocation = {{{convocation2|}}} | country = {{{country2|}}} | deputy = {{{deputy2|}}} | deputyminister = {{{deputyminister2|}}} | headminister = {{{headminister2|}}} | district = {{{district2|}}} | firstminister = {{{firstminister2|}}} | governor-general = {{{governor-general2|}}} | governor_general = {{{governor_general2|}}} | governor = {{{governor2|}}} | jr/sr = {{{jr/sr2|}}} | jr/sr and state = {{{jr/sr and state2|}}} | leader = {{{leader2|}}} | legislature = {{{legislature2|}}} | lieutenant_governor = {{{lieutenant_governor2|}}} | lieutenant = {{{lieutenant2|}}} | majority_leader = {{#if: {{{majorityleader2|}}} | {{{majorityleader2}}} | {{{majority_leader2|}}} }} | minister_from = {{{minister_from2|}}} | minority_floor_leader = {{{minority_floor_leader2|}}} | majority_floor_leader = {{{majority_floor_leader2|}}} | majority = {{{majority2|}}} | minister = {{{minister2|}}} | minority_leader = {{#if: {{{minorityleader2|}}} | {{{minorityleader2}}} | {{{minority_leader2|}}} }} | monarch = {{{monarch2|}}} | nominator = {{{nominator2|}}} | office = {{{office2|}}} | order = {{{order2|}}} | parliament = {{{parliament2|}}} | parliamentarygroup = {{{parliamentarygroup2|}}} | predecessor = {{{predecessor2|}}} | preceding = {{{preceding2|}}} | preceded = {{{preceded2|}}} | premier = {{{premier2|}}} | president = {{{president2|}}} | primeminister = {{{primeminister2|}}} | riding = {{{riding2|}}} | state_assembly = {{{state_assembly2|}}} | state_delegate = {{{state_delegate2|}}} | state_house = {{{state_house2|}}} | state_legislature = {{{state_legislature2|}}} | state_senate = {{{state_senate2|}}} | state = {{{state2|}}} | status = {{{status2|}}} | subterm = {{{subterm2|}}} | suboffice = {{{suboffice2|}}} | succeeded = {{{succeeded2|}}} | succeeding = {{{succeeding2|}}} | successor = {{{successor2|}}} | taoiseach = {{{taoiseach2|}}} | termlabel = {{{term_label2|{{{termlabel2|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend2|}}}|{{{termend2}}}|{{{term_end2|}}}}} | termstart = {{#if:{{{termstart2|}}}|{{{termstart2}}}|{{{term_start2|}}}}} | term = {{{term2|}}} | title = {{{title2|}}} | vicegovernor = {{{vicegovernor2|}}} | vicepresident = {{{vicepresident2|}}} | vicepremier = {{{vicepremier2|}}} | viceprimeminister = {{{viceprimeminister2|}}} | party = {{{party|}}} | prior_term = {{{prior_term2|}}} }}}}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname3|}}} | 1namedata = {{{1namedata3|}}} | 2blankname = {{{2blankname3|}}} | 2namedata = {{{2namedata3|}}} | 3blankname = {{{3blankname3|}}} | 3namedata = {{{3namedata3|}}} | 4blankname = {{{4blankname3|}}} | 4namedata = {{{4namedata3|}}} | 5blankname = {{{5blankname3|}}} | 5namedata = {{{5namedata3|}}} | alongside = {{{alongside3|}}} | ambassador_from = {{{ambassador_from3|}}} | appointer = {{#if: {{{appointer3|}}} | {{{appointer3}}} | {{{appointed3|}}} }} | assembly = {{{assembly3|}}} | assuming = {{{assuming3|}}} | chancellor = {{{chancellor3|}}} | co-leader = {{{co-leader3|}}} | constituency_{{#if:{{{constituency_AM3|}}}|AM|MP}} = {{#if: {{{constituency_AM3|}}} | {{{constituency_AM3}}} | {{{constituency_MP3|}}} }} | constituency = {{{constituency3|}}} | convocation = {{{convocation3|}}} | country = {{{country3|}}} | deputy = {{{deputy3|}}} | deputyminister = {{{deputyminister3|}}} | headminister = {{{headminister3|}}} | district = {{{district3|}}} | firstminister = {{{firstminister3|}}} | governor-general = {{{governor-general3|}}} | governor_general = {{{governor_general3|}}} | governor = {{{governor3|}}} | jr/sr = {{{jr/sr3|}}} | jr/sr and state = {{{jr/sr and state3|}}} | leader = {{{leader3|}}} | legislature = {{{legislature3|}}} | lieutenant_governor = {{{lieutenant_governor3|}}} | lieutenant = {{{lieutenant3|}}} | minority_floor_leader = {{{minority_floor_leader3|}}} | minister_from = {{{minister_from3|}}} | majority_floor_leader = {{{majority_floor_leader3|}}} | majority_leader = {{#if: {{{majorityleader3|}}} | {{{majorityleader3}}} | {{{majority_leader3|}}} }} | majority = {{{majority3|}}} | minister = {{{minister3|}}} | minority_leader = {{#if: {{{minorityleader3|}}} | {{{minorityleader3}}} | {{{minority_leader3|}}} }} | monarch = {{{monarch3|}}} | nominator = {{{nominator3|}}} | office = {{{office3|}}} | order = {{{order3|}}} | parliament = {{{parliament3|}}} | parliamentarygroup = {{{parliamentarygroup3|}}} | predecessor = {{{predecessor3|}}} | preceding = {{{preceding3|}}} | preceded = {{{preceded3|}}} | premier = {{{premier3|}}} | president = {{{president3|}}} | primeminister = {{{primeminister3|}}} | riding = {{{riding3|}}} | state_assembly = {{{state_assembly3|}}} | state_delegate = {{{state_delegate3|}}} | state_house = {{{state_house3|}}} | state_legislature = {{{state_legislature3|}}} | state_senate = {{{state_senate3|}}} | state = {{{state3|}}} | status = {{{status3|}}} | subterm = {{{subterm3|}}} | suboffice = {{{suboffice3|}}} | succeeded = {{{succeeded3|}}} | succeeding = {{{succeeding3|}}} | successor = {{{successor3|}}} | taoiseach = {{{taoiseach3|}}} | termlabel = {{{term_label3|{{{termlabel3|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend3|}}}|{{{termend3}}}|{{{term_end3|}}}}} | termstart = {{#if:{{{termstart3|}}}|{{{termstart3}}}|{{{term_start3|}}}}} | term = {{{term3|}}} | title = {{{title3|}}} | vicegovernor = {{{vicegovernor3|}}} | vicepresident = {{{vicepresident3|}}} | vicepremier = {{{vicepremier3|}}} | viceprimeminister = {{{viceprimeminister3|}}} | party = {{{party|}}} | prior_term = {{{prior_term3|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname4|}}} | 1namedata = {{{1namedata4|}}} | 2blankname = {{{2blankname4|}}} | 2namedata = {{{2namedata4|}}} | 3blankname = {{{3blankname4|}}} | 3namedata = {{{3namedata4|}}} | 4blankname = {{{4blankname4|}}} | 4namedata = {{{4namedata4|}}} | 5blankname = {{{5blankname4|}}} | 5namedata = {{{5namedata4|}}} | alongside = {{{alongside4|}}} | ambassador_from = {{{ambassador_from4|}}} | appointer = {{#if: {{{appointer4|}}} | {{{appointer4}}} | {{{appointed4|}}} }} | assembly = {{{assembly4|}}} | assuming = {{{assuming4|}}} | chancellor = {{{chancellor4|}}} | co-leader = {{{co-leader4|}}} | constituency_{{#if:{{{constituency_AM4|}}}|AM|MP}} = {{#if: {{{constituency_AM4|}}} | {{{constituency_AM4}}} | {{{constituency_MP4|}}} }} | constituency = {{{constituency4|}}} | convocation = {{{convocation4|}}} | country = {{{country4|}}} | deputy = {{{deputy4|}}} | deputyminister = {{{deputyminister4|}}} | headminister = {{{headminister4|}}} | district = {{{district4|}}} | firstminister = {{{firstminister4|}}} | governor-general = {{{governor-general4|}}} | governor_general = {{{governor_general4|}}} | governor = {{{governor4|}}} | jr/sr = {{{jr/sr4|}}} | jr/sr and state = {{{jr/sr and state4|}}} | leader = {{{leader4|}}} | legislature = {{{legislature4|}}} | lieutenant_governor = {{{lieutenant_governor4|}}} | lieutenant = {{{lieutenant4|}}} | minister_from = {{{minister_from4|}}} | minority_floor_leader = {{{minority_floor_leader4|}}} | majority_floor_leader = {{{majority_floor_leader4|}}} | majority_leader = {{#if: {{{majorityleader4|}}} | {{{majorityleader4}}} | {{{majority_leader4|}}} }} | majority = {{{majority4|}}} | minister = {{{minister4|}}} | minority_leader = {{#if: {{{minorityleader4|}}} | {{{minorityleader4}}} | {{{minority_leader4|}}} }} | monarch = {{{monarch4|}}} | nominator = {{{nominator4|}}} | office = {{{office4|}}} | order = {{{order4|}}} | parliament = {{{parliament4|}}} | parliamentarygroup = {{{parliamentarygroup4|}}} | predecessor = {{{predecessor4|}}} | preceding = {{{preceding4|}}} | preceded = {{{preceded4|}}} | premier = {{{premier4|}}} | president = {{{president4|}}} | primeminister = {{{primeminister4|}}} | riding = {{{riding4|}}} | state_assembly = {{{state_assembly4|}}} | state_delegate = {{{state_delegate4|}}} | state_house = {{{state_house4|}}} | state_legislature = {{{state_legislature4|}}} | state_senate = {{{state_senate4|}}} | state = {{{state4|}}} | status = {{{status4|}}} | subterm = {{{subterm4|}}} | suboffice = {{{suboffice4|}}} | succeeded = {{{succeeded4|}}} | succeeding = {{{succeeding4|}}} | successor = {{{successor4|}}} | taoiseach = {{{taoiseach4|}}} | termlabel = {{{term_label4|{{{termlabel4|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend4|}}}|{{{termend4}}}|{{{term_end4|}}}}} | termstart = {{#if:{{{termstart4|}}}|{{{termstart4}}}|{{{term_start4|}}}}} | term = {{{term4|}}} | title = {{{title4|}}} | vicegovernor = {{{vicegovernor4|}}} | vicepresident = {{{vicepresident4|}}} | vicepremier = {{{vicepremier4|}}} | viceprimeminister = {{{viceprimeminister4|}}} | party = {{{party|}}} | prior_term = {{{prior_term4|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname5|}}} | 1namedata = {{{1namedata5|}}} | 2blankname = {{{2blankname5|}}} | 2namedata = {{{2namedata5|}}} | 3blankname = {{{3blankname5|}}} | 3namedata = {{{3namedata5|}}} | 4blankname = {{{4blankname5|}}} | 4namedata = {{{4namedata5|}}} | 5blankname = {{{5blankname5|}}} | 5namedata = {{{5namedata5|}}} | alongside = {{{alongside5|}}} | ambassador_from = {{{ambassador_from5|}}} | appointer = {{#if: {{{appointer5|}}} | {{{appointer5}}} | {{{appointed5|}}} }} | assembly = {{{assembly5|}}} | assuming = {{{assuming5|}}} | chancellor = {{{chancellor5|}}} | co-leader = {{{co-leader5|}}} | constituency_{{#if:{{{constituency_AM5|}}}|AM|MP}} = {{#if: {{{constituency_AM5|}}} | {{{constituency_AM5}}} | {{{constituency_MP5|}}} }} | constituency = {{{constituency5|}}} | convocation = {{{convocation5|}}} | country = {{{country5|}}} | deputy = {{{deputy5|}}} | deputyminister = {{{deputyminister5|}}} | headminister = {{{headminister5|}}} | district = {{{district5|}}} | firstminister = {{{firstminister5|}}} | governor-general = {{{governor-general5|}}} | governor_general = {{{governor_general5|}}} | governor = {{{governor5|}}} | jr/sr = {{{jr/sr5|}}} | jr/sr and state = {{{jr/sr and state5|}}} | leader = {{{leader5|}}} | legislature = {{{legislature5|}}} | lieutenant_governor = {{{lieutenant_governor5|}}} | lieutenant = {{{lieutenant5|}}} | minister_from = {{{minister_from5|}}} | minority_floor_leader = {{{minority_floor_leader5|}}} | majority_floor_leader = {{{majority_floor_leader5|}}} | majority_leader = {{#if: {{{majorityleader5|}}} | {{{majorityleader5}}} | {{{majority_leader5|}}} }} | majority = {{{majority5|}}} | minister = {{{minister5|}}} | minority_leader = {{#if: {{{minorityleader5|}}} | {{{minorityleader5}}} | {{{minority_leader5|}}} }} | monarch = {{{monarch5|}}} | nominator = {{{nominator5|}}} | office = {{{office5|}}} | order = {{{order5|}}} | parliament = {{{parliament5|}}} | parliamentarygroup = {{{parliamentarygroup5|}}} | predecessor = {{{predecessor5|}}} | preceding = {{{preceding5|}}} | preceded = {{{preceded5|}}} | premier = {{{premier5|}}} | president = {{{president5|}}} | primeminister = {{{primeminister5|}}} | riding = {{{riding5|}}} | state_assembly = {{{state_assembly5|}}} | state_delegate = {{{state_delegate5|}}} | state_house = {{{state_house5|}}} | state_legislature = {{{state_legislature5|}}} | state_senate = {{{state_senate5|}}} | state = {{{state5|}}} | status = {{{status5|}}} | subterm = {{{subterm5|}}} | suboffice = {{{suboffice5|}}} | succeeded = {{{succeeded5|}}} | succeeding = {{{succeeding5|}}} | successor = {{{successor5|}}} | taoiseach = {{{taoiseach5|}}} | termlabel = {{{term_label5|{{{termlabel5|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend5|}}}|{{{termend5}}}|{{{term_end5|}}}}} | termstart = {{#if:{{{termstart5|}}}|{{{termstart5}}}|{{{term_start5|}}}}} | term = {{{term5|}}} | title = {{{title5|}}} | vicegovernor = {{{vicegovernor5|}}} | vicepresident = {{{vicepresident5|}}} | vicepremier = {{{vicepremier5|}}} | viceprimeminister = {{{viceprimeminister5|}}} | party = {{{party|}}} | prior_term = {{{prior_term5|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname6|}}} | 1namedata = {{{1namedata6|}}} | 2blankname = {{{2blankname6|}}} | 2namedata = {{{2namedata6|}}} | 3blankname = {{{3blankname6|}}} | 3namedata = {{{3namedata6|}}} | 4blankname = {{{4blankname6|}}} | 4namedata = {{{4namedata6|}}} | 5blankname = {{{5blankname6|}}} | 5namedata = {{{5namedata6|}}} | alongside = {{{alongside6|}}} | ambassador_from = {{{ambassador_from6|}}} | appointer = {{#if: {{{appointer6|}}} | {{{appointer6}}} | {{{appointed6|}}} }} | assembly = {{{assembly6|}}} | assuming = {{{assuming6|}}} | chancellor = {{{chancellor6|}}} | co-leader = {{{co-leader6|}}} | constituency_{{#if:{{{constituency_AM6|}}}|AM|MP}} = {{#if: {{{constituency_AM6|}}} | {{{constituency_AM6}}} | {{{constituency_MP6|}}} }} | constituency = {{{constituency6|}}} | convocation = {{{convocation6|}}} | country = {{{country6|}}} | deputy = {{{deputy6|}}} | deputyminister = {{{deputyminister6|}}} | headminister = {{{headminister6|}}} | district = {{{district6|}}} | firstminister = {{{firstminister6|}}} | governor-general = {{{governor-general6|}}} | governor_general = {{{governor_general6|}}} | governor = {{{governor6|}}} | jr/sr = {{{jr/sr6|}}} | jr/sr and state = {{{jr/sr and state6|}}} | leader = {{{leader6|}}} | legislature = {{{legislature6|}}} | lieutenant_governor = {{{lieutenant_governor6|}}} | lieutenant = {{{lieutenant6|}}} | minority_floor_leader = {{{minority_floor_leader6|}}} | minister_from = {{{minister_from6|}}} | majority_floor_leader = {{{majority_floor_leader6|}}} | majority_leader = {{#if: {{{majorityleader6|}}} | {{{majorityleader6}}} | {{{majority_leader6|}}} }} | majority = {{{majority6|}}} | minister = {{{minister6|}}} | minority_leader = {{#if: {{{minorityleader6|}}} | {{{minorityleader6}}} | {{{minority_leader6|}}} }} | monarch = {{{monarch6|}}} | nominator = {{{nominator6|}}} | office = {{{office6|}}} | order = {{{order6|}}} | parliament = {{{parliament6|}}} | parliamentarygroup = {{{parliamentarygroup6|}}} | predecessor = {{{predecessor6|}}} | preceding = {{{preceding6|}}} | preceded = {{{preceded6|}}} | premier = {{{premier6|}}} | president = {{{president6|}}} | primeminister = {{{primeminister6|}}} | riding = {{{riding6|}}} | state_assembly = {{{state_assembly6|}}} | state_delegate = {{{state_delegate6|}}} | state_house = {{{state_house6|}}} | state_legislature = {{{state_legislature6|}}} | state_senate = {{{state_senate6|}}} | state = {{{state6|}}} | status = {{{status6|}}} | subterm = {{{subterm6|}}} | suboffice = {{{suboffice6|}}} | succeeded = {{{succeeded6|}}} | succeeding = {{{succeeding6|}}} | successor = {{{successor6|}}} | taoiseach = {{{taoiseach6|}}} | termlabel = {{{term_label6|{{{termlabel6|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend6|}}}|{{{termend6}}}|{{{term_end6|}}}}} | termstart = {{#if:{{{termstart6|}}}|{{{termstart6}}}|{{{term_start6|}}}}} | term = {{{term6|}}} | title = {{{title6|}}} | vicegovernor = {{{vicegovernor6|}}} | vicepresident = {{{vicepresident6|}}} | vicepremier = {{{vicepremier6|}}} | viceprimeminister = {{{viceprimeminister6|}}} | party = {{{party|}}} | prior_term = {{{prior_term6|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname7|}}} | 1namedata = {{{1namedata7|}}} | 2blankname = {{{2blankname7|}}} | 2namedata = {{{2namedata7|}}} | 3blankname = {{{3blankname7|}}} | 3namedata = {{{3namedata7|}}} | 4blankname = {{{4blankname7|}}} | 4namedata = {{{4namedata7|}}} | 5blankname = {{{5blankname7|}}} | 5namedata = {{{5namedata7|}}} | alongside = {{{alongside7|}}} | ambassador_from = {{{ambassador_from7|}}} | appointer = {{#if: {{{appointer7|}}} | {{{appointer7}}} | {{{appointed7|}}} }} | assembly = {{{assembly7|}}} | assuming = {{{assuming7|}}} | chancellor = {{{chancellor7|}}} | co-leader = {{{co-leader7|}}} | constituency_{{#if:{{{constituency_AM7|}}}|AM|MP}} = {{#if: {{{constituency_AM7|}}} | {{{constituency_AM7}}} | {{{constituency_MP7|}}} }} | constituency = {{{constituency7|}}} | convocation = {{{convocation7|}}} | country = {{{country7|}}} | deputy = {{{deputy7|}}} | deputyminister = {{{deputyminister7|}}} | headminister = {{{headminister7|}}} | district = {{{district7|}}} | firstminister = {{{firstminister7|}}} | governor-general = {{{governor-general7|}}} | governor_general = {{{governor_general7|}}} | governor = {{{governor7|}}} | jr/sr = {{{jr/sr7|}}} | jr/sr and state = {{{jr/sr and state7|}}} | leader = {{{leader7|}}} | legislature = {{{legislature7|}}} | lieutenant_governor = {{{lieutenant_governor7|}}} | lieutenant = {{{lieutenant7|}}} | minister_from = {{{minister_from7|}}} | minority_floor_leader = {{{minority_floor_leader7|}}} | majority_floor_leader = {{{majority_floor_leader7|}}} | majority_leader = {{#if: {{{majorityleader7|}}} | {{{majorityleader7}}} | {{{majority_leader7|}}} }} | majority = {{{majority7|}}} | minister = {{{minister7|}}} | minority_leader = {{#if: {{{minorityleader7|}}} | {{{minorityleader7}}} | {{{minority_leader7|}}} }} | monarch = {{{monarch7|}}} | nominator = {{{nominator7|}}} | office = {{{office7|}}} | order = {{{order7|}}} | parliament = {{{parliament7|}}} | parliamentarygroup = {{{parliamentarygroup7|}}} | predecessor = {{{predecessor7|}}} | preceding = {{{preceding7|}}} | preceded = {{{preceded7|}}} | premier = {{{premier7|}}} | president = {{{president7|}}} | primeminister = {{{primeminister7|}}} | riding = {{{riding7|}}} | state_assembly = {{{state_assembly7|}}} | state_delegate = {{{state_delegate7|}}} | state_house = {{{state_house7|}}} | state_legislature = {{{state_legislature7|}}} | state_senate = {{{state_senate7|}}} | state = {{{state7|}}} | status = {{{status7|}}} | subterm = {{{subterm7|}}} | suboffice = {{{suboffice7|}}} | succeeded = {{{succeeded7|}}} | succeeding = {{{succeeding7|}}} | successor = {{{successor7|}}} | taoiseach = {{{taoiseach7|}}} | termlabel = {{{term_label7|{{{termlabel7|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend7|}}}|{{{termend7}}}|{{{term_end7|}}}}} | termstart = {{#if:{{{termstart7|}}}|{{{termstart7}}}|{{{term_start7|}}}}} | term = {{{term7|}}} | title = {{{title7|}}} | vicegovernor = {{{vicegovernor7|}}} | vicepresident = {{{vicepresident7|}}} | vicepremier = {{{vicepremier7|}}} | viceprimeminister = {{{viceprimeminister7|}}} | party = {{{party|}}} | prior_term = {{{prior_term7|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname8|}}} | 1namedata = {{{1namedata8|}}} | 2blankname = {{{2blankname8|}}} | 2namedata = {{{2namedata8|}}} | 3blankname = {{{3blankname8|}}} | 3namedata = {{{3namedata8|}}} | 4blankname = {{{4blankname8|}}} | 4namedata = {{{4namedata8|}}} | 5blankname = {{{5blankname8|}}} | 5namedata = {{{5namedata8|}}} | alongside = {{{alongside8|}}} | ambassador_from = {{{ambassador_from8|}}} | appointer = {{#if: {{{appointer8|}}} | {{{appointer8}}} | {{{appointed8|}}} }} | assembly = {{{assembly8|}}} | assuming = {{{assuming8|}}} | chancellor = {{{chancellor8|}}} | co-leader = {{{co-leader8|}}} | constituency_{{#if:{{{constituency_AM8|}}}|AM|MP}} = {{#if: {{{constituency_AM8|}}} | {{{constituency_AM8}}} | {{{constituency_MP8|}}} }} | constituency = {{{constituency8|}}} | convocation = {{{convocation8|}}} | country = {{{country8|}}} | deputy = {{{deputy8|}}} | deputyminister = {{{deputyminister8|}}} | headminister = {{{headminister8|}}} | district = {{{district8|}}} | firstminister = {{{firstminister8|}}} | governor-general = {{{governor-general8|}}} | governor_general = {{{governor_general8|}}} | governor = {{{governor8|}}} | jr/sr = {{{jr/sr8|}}} | jr/sr and state = {{{jr/sr and state8|}}} | leader = {{{leader8|}}} | legislature = {{{legislature8|}}} | lieutenant_governor = {{{lieutenant_governor8|}}} | lieutenant = {{{lieutenant8|}}} | minister_from = {{{minister_from8|}}} | minority_floor_leader = {{{minority_floor_leader8|}}} | majority_floor_leader = {{{majority_floor_leader8|}}} | majority_leader = {{#if: {{{majorityleader8|}}} | {{{majorityleader8}}} | {{{majority_leader8|}}} }} | majority = {{{majority8|}}} | minister = {{{minister8|}}} | minority_leader = {{#if: {{{minorityleader8|}}} | {{{minorityleader8}}} | {{{minority_leader8|}}} }} | monarch = {{{monarch8|}}} | nominator = {{{nominator8|}}} | office = {{{office8|}}} | order = {{{order8|}}} | parliament = {{{parliament8|}}} | parliamentarygroup = {{{parliamentarygroup8|}}} | predecessor = {{{predecessor8|}}} | preceding = {{{preceding8|}}} | preceded = {{{preceded8|}}} | premier = {{{premier8|}}} | president = {{{president8|}}} | primeminister = {{{primeminister8|}}} | riding = {{{riding8|}}} | state_assembly = {{{state_assembly8|}}} | state_delegate = {{{state_delegate8|}}} | state_house = {{{state_house8|}}} | state_legislature = {{{state_legislature8|}}} | state_senate = {{{state_senate8|}}} | state = {{{state8|}}} | status = {{{status8|}}} | subterm = {{{subterm8|}}} | suboffice = {{{suboffice8|}}} | succeeded = {{{succeeded8|}}} | succeeding = {{{succeeding8|}}} | successor = {{{successor8|}}} | taoiseach = {{{taoiseach8|}}} | termlabel = {{{term_label8|{{{termlabel8|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend8|}}}|{{{termend8}}}|{{{term_end8|}}}}} | termstart = {{#if:{{{termstart8|}}}|{{{termstart8}}}|{{{term_start8|}}}}} | term = {{{term8|}}} | title = {{{title8|}}} | vicegovernor = {{{vicegovernor8|}}} | vicepresident = {{{vicepresident8|}}} | vicepremier = {{{vicepremier8|}}} | viceprimeminister = {{{viceprimeminister8|}}} | party = {{{party|}}} | prior_term = {{{prior_term8|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname9|}}} | 1namedata = {{{1namedata9|}}} | 2blankname = {{{2blankname9|}}} | 2namedata = {{{2namedata9|}}} | 3blankname = {{{3blankname9|}}} | 3namedata = {{{3namedata9|}}} | 4blankname = {{{4blankname9|}}} | 4namedata = {{{4namedata9|}}} | 5blankname = {{{5blankname9|}}} | 5namedata = {{{5namedata9|}}} | alongside = {{{alongside9|}}} | ambassador_from = {{{ambassador_from9|}}} | appointer = {{#if: {{{appointer9|}}} | {{{appointer9}}} | {{{appointed9|}}} }} | assembly = {{{assembly9|}}} | assuming = {{{assuming9|}}} | chancellor = {{{chancellor9|}}} | co-leader = {{{co-leader9|}}} | constituency_{{#if:{{{constituency_AM9|}}}|AM|MP}} = {{#if: {{{constituency_AM9|}}} | {{{constituency_AM9}}} | {{{constituency_MP9|}}} }} | constituency = {{{constituency9|}}} | convocation = {{{convocation9|}}} | country = {{{country9|}}} | deputy = {{{deputy9|}}} | deputyminister = {{{deputyminister9|}}} | headminister = {{{headminister9|}}} | district = {{{district9|}}} | firstminister = {{{firstminister9|}}} | governor-general = {{{governor-general9|}}} | governor_general = {{{governor_general9|}}} | governor = {{{governor9|}}} | jr/sr = {{{jr/sr9|}}} | jr/sr and state = {{{jr/sr and state9|}}} | leader = {{{leader9|}}} | legislature = {{{legislature9|}}} | lieutenant_governor = {{{lieutenant_governor9|}}} | lieutenant = {{{lieutenant9|}}} | minister_from = {{{minister_from9|}}} | minority_floor_leader = {{{minority_floor_leader9|}}} | majority_floor_leader = {{{majority_floor_leader9|}}} | majority_leader = {{#if: {{{majorityleader9|}}} | {{{majorityleader9}}} | {{{majority_leader9|}}} }} | majority = {{{majority9|}}} | minister = {{{minister9|}}} | minority_leader = {{#if: {{{minorityleader9|}}} | {{{minorityleader9}}} | {{{minority_leader9|}}} }} | monarch = {{{monarch9|}}} | nominator = {{{nominator9|}}} | office = {{{office9|}}} | order = {{{order9|}}} | parliament = {{{parliament9|}}} | parliamentarygroup = {{{parliamentarygroup9|}}} | predecessor = {{{predecessor9|}}} | preceding = {{{preceding9|}}} | preceded = {{{preceded9|}}} | premier = {{{premier9|}}} | president = {{{president9|}}} | primeminister = {{{primeminister9|}}} | riding = {{{riding9|}}} | state_assembly = {{{state_assembly9|}}} | state_delegate = {{{state_delegate9|}}} | state_house = {{{state_house9|}}} | state_legislature = {{{state_legislature9|}}} | state_senate = {{{state_senate9|}}} | state = {{{state9|}}} | status = {{{status9|}}} | subterm = {{{subterm9|}}} | suboffice = {{{suboffice9|}}} | succeeded = {{{succeeded9|}}} | succeeding = {{{succeeding9|}}} | successor = {{{successor9|}}} | taoiseach = {{{taoiseach9|}}} | termlabel = {{{term_label9|{{{termlabel9|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend9|}}}|{{{termend9}}}|{{{term_end9|}}}}} | termstart = {{#if:{{{termstart9|}}}|{{{termstart9}}}|{{{term_start9|}}}}} | term = {{{term9|}}} | title = {{{title9|}}} | vicegovernor = {{{vicegovernor9|}}} | vicepresident = {{{vicepresident9|}}} | vicepremier = {{{vicepremier9|}}} | viceprimeminister = {{{viceprimeminister9|}}} | party = {{{party|}}} | prior_term = {{{prior_term9|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname10|}}} | 1namedata = {{{1namedata10|}}} | 2blankname = {{{2blankname10|}}} | 2namedata = {{{2namedata10|}}} | 3blankname = {{{3blankname10|}}} | 3namedata = {{{3namedata10|}}} | 4blankname = {{{4blankname10|}}} | 4namedata = {{{4namedata10|}}} | 5blankname = {{{5blankname10|}}} | 5namedata = {{{5namedata10|}}} | alongside = {{{alongside10|}}} | ambassador_from = {{{ambassador_from10|}}} | appointer = {{#if: {{{appointer10|}}} | {{{appointer10}}} | {{{appointed10|}}} }} | assembly = {{{assembly10|}}} | assuming = {{{assuming10|}}} | chancellor = {{{chancellor10|}}} | co-leader = {{{co-leader10|}}} | constituency_{{#if:{{{constituency_AM10|}}}|AM|MP}} = {{#if: {{{constituency_AM10|}}} | {{{constituency_AM10}}} | {{{constituency_MP10|}}} }} | constituency = {{{constituency10|}}} | convocation = {{{convocation10|}}} | country = {{{country10|}}} | deputy = {{{deputy10|}}} | deputyminister = {{{deputyminister10|}}} | headminister = {{{headminister10|}}} | district = {{{district10|}}} | firstminister = {{{firstminister10|}}} | governor-general = {{{governor-general10|}}} | governor_general = {{{governor_general10|}}} | governor = {{{governor10|}}} | jr/sr = {{{jr/sr10|}}} | jr/sr and state = {{{jr/sr and state10|}}} | leader = {{{leader10|}}} | legislature = {{{legislature10|}}} | lieutenant_governor = {{{lieutenant_governor10|}}} | lieutenant = {{{lieutenant10|}}} | minister_from = {{{minister_from10|}}} | minority_floor_leader = {{{minority_floor_leader10|}}} | majority_floor_leader = {{{majority_floor_leader10|}}} | majority_leader = {{#if: {{{majorityleader10|}}} | {{{majorityleader10}}} | {{{majority_leader10|}}} }} | majority = {{{majority10|}}} | minister = {{{minister10|}}} | minority_leader = {{#if: {{{minorityleader10|}}} | {{{minorityleader10}}} | {{{minority_leader10|}}} }} | monarch = {{{monarch10|}}} | nominator = {{{nominator10|}}} | office = {{{office10|}}} | order = {{{order10|}}} | parliament = {{{parliament10|}}} | parliamentarygroup = {{{parliamentarygroup10|}}} | predecessor = {{{predecessor10|}}} | preceding = {{{preceding10|}}} | preceded = {{{preceded10|}}} | premier = {{{premier10|}}} | president = {{{president10|}}} | primeminister = {{{primeminister10|}}} | riding = {{{riding10|}}} | state_assembly = {{{state_assembly10|}}} | state_delegate = {{{state_delegate10|}}} | state_house = {{{state_house10|}}} | state_legislature = {{{state_legislature10|}}} | state_senate = {{{state_senate10|}}} | state = {{{state10|}}} | status = {{{status10|}}} | subterm = {{{subterm10|}}} | suboffice = {{{suboffice10|}}} | succeeded = {{{succeeded10|}}} | succeeding = {{{succeeding10|}}} | successor = {{{successor10|}}} | taoiseach = {{{taoiseach10|}}} | termlabel = {{{term_label10|{{{termlabel10|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend10|}}}|{{{termend10}}}|{{{term_end10|}}}}} | termstart = {{#if:{{{termstart10|}}}|{{{termstart10}}}|{{{term_start10|}}}}} | term = {{{term10|}}} | title = {{{title10|}}} | vicegovernor = {{{vicegovernor10|}}} | vicepresident = {{{vicepresident10|}}} | vicepremier = {{{vicepremier10|}}} | viceprimeminister = {{{viceprimeminister10|}}} | party = {{{party|}}} | prior_term = {{{prior_term10|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname11|}}} | 1namedata = {{{1namedata11|}}} | 2blankname = {{{2blankname11|}}} | 2namedata = {{{2namedata11|}}} | 3blankname = {{{3blankname11|}}} | 3namedata = {{{3namedata11|}}} | 4blankname = {{{4blankname11|}}} | 4namedata = {{{4namedata11|}}} | 5blankname = {{{5blankname11|}}} | 5namedata = {{{5namedata11|}}} | alongside = {{{alongside11|}}} | ambassador_from = {{{ambassador_from11|}}} | appointer = {{#if: {{{appointer11|}}} | {{{appointer11}}} | {{{appointed11|}}} }} | assembly = {{{assembly11|}}} | assuming = {{{assuming11|}}} | chancellor = {{{chancellor11|}}} | co-leader = {{{co-leader11|}}} | constituency_{{#if:{{{constituency_AM11|}}}|AM|MP}} = {{#if: {{{constituency_AM11|}}} | {{{constituency_AM11}}} | {{{constituency_MP11|}}} }} | constituency = {{{constituency11|}}} | convocation = {{{convocation11|}}} | country = {{{country11|}}} | deputy = {{{deputy11|}}} | deputyminister = {{{deputyminister11|}}} | headminister = {{{headminister11|}}} | district = {{{district11|}}} | firstminister = {{{firstminister11|}}} | governor-general = {{{governor-general11|}}} | governor_general = {{{governor_general11|}}} | governor = {{{governor11|}}} | jr/sr = {{{jr/sr11|}}} | jr/sr and state = {{{jr/sr and state11|}}} | leader = {{{leader11|}}} | legislature = {{{legislature11|}}} | lieutenant_governor = {{{lieutenant_governor11|}}} | lieutenant = {{{lieutenant11|}}} | minister_from = {{{minister_from11|}}} | minority_floor_leader = {{{minority_floor_leader11|}}} | majority_floor_leader = {{{majority_floor_leader11|}}} | majority_leader = {{#if: {{{majorityleader11|}}} | {{{majorityleader11}}} | {{{majority_leader11|}}} }} | majority = {{{majority11|}}} | minister = {{{minister11|}}} | minority_leader = {{#if: {{{minorityleader11|}}} | {{{minorityleader11}}} | {{{minority_leader11|}}} }} | monarch = {{{monarch11|}}} | nominator = {{{nominator11|}}} | office = {{{office11|}}} | order = {{{order11|}}} | parliament = {{{parliament11|}}} | parliamentarygroup = {{{parliamentarygroup11|}}} | predecessor = {{{predecessor11|}}} | preceding = {{{preceding11|}}} | preceded = {{{preceded11|}}} | premier = {{{premier11|}}} | president = {{{president11|}}} | primeminister = {{{primeminister11|}}} | riding = {{{riding11|}}} | state_assembly = {{{state_assembly11|}}} | state_delegate = {{{state_delegate11|}}} | state_house = {{{state_house11|}}} | state_legislature = {{{state_legislature11|}}} | state_senate = {{{state_senate11|}}} | state = {{{state11|}}} | status = {{{status11|}}} | subterm = {{{subterm11|}}} | suboffice = {{{suboffice11|}}} | succeeded = {{{succeeded11|}}} | succeeding = {{{succeeding11|}}} | successor = {{{successor11|}}} | taoiseach = {{{taoiseach11|}}} | termlabel = {{{term_label11|{{{termlabel11|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend11|}}}|{{{termend11}}}|{{{term_end11|}}}}} | termstart = {{#if:{{{termstart11|}}}|{{{termstart11}}}|{{{term_start11|}}}}} | term = {{{term11|}}} | title = {{{title11|}}} | vicegovernor = {{{vicegovernor11|}}} | vicepresident = {{{vicepresident11|}}} | vicepremier = {{{vicepremier11|}}} | viceprimeminister = {{{viceprimeminister11|}}} | party = {{{party|}}} | prior_term = {{{prior_term11|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname12|}}} | 1namedata = {{{1namedata12|}}} | 2blankname = {{{2blankname12|}}} | 2namedata = {{{2namedata12|}}} | 3blankname = {{{3blankname12|}}} | 3namedata = {{{3namedata12|}}} | 4blankname = {{{4blankname12|}}} | 4namedata = {{{4namedata12|}}} | 5blankname = {{{5blankname12|}}} | 5namedata = {{{5namedata12|}}} | alongside = {{{alongside12|}}} | ambassador_from = {{{ambassador_from12|}}} | appointer = {{#if: {{{appointer12|}}} | {{{appointer12}}} | {{{appointed12|}}} }} | assembly = {{{assembly12|}}} | assuming = {{{assuming12|}}} | chancellor = {{{chancellor12|}}} | co-leader = {{{co-leader12|}}} | constituency_{{#if:{{{constituency_AM12|}}}|AM|MP}} = {{#if: {{{constituency_AM12|}}} | {{{constituency_AM12}}} | {{{constituency_MP12|}}} }} | constituency = {{{constituency12|}}} | convocation = {{{convocation12|}}} | country = {{{country12|}}} | deputy = {{{deputy12|}}} | deputyminister = {{{deputyminister12|}}} | headminister = {{{headminister12|}}} | district = {{{district12|}}} | firstminister = {{{firstminister12|}}} | governor-general = {{{governor-general12|}}} | governor_general = {{{governor_general12|}}} | governor = {{{governor12|}}} | jr/sr = {{{jr/sr12|}}} | jr/sr and state = {{{jr/sr and state12|}}} | leader = {{{leader12|}}} | legislature = {{{legislature12|}}} | lieutenant_governor = {{{lieutenant_governor12|}}} | lieutenant = {{{lieutenant12|}}} | minister_from = {{{minister_from12|}}} | minority_floor_leader = {{{minority_floor_leader12|}}} | majority_floor_leader = {{{majority_floor_leader12|}}} | majority_leader = {{#if: {{{majorityleader12|}}} | {{{majorityleader12}}} | {{{majority_leader12|}}} }} | majority = {{{majority12|}}} | minister = {{{minister12|}}} | minority_leader = {{#if: {{{minorityleader12|}}} | {{{minorityleader12}}} | {{{minority_leader12|}}} }} | monarch = {{{monarch12|}}} | nominator = {{{nominator12|}}} | office = {{{office12|}}} | order = {{{order12|}}} | parliament = {{{parliament12|}}} | parliamentarygroup = {{{parliamentarygroup12|}}} | predecessor = {{{predecessor12|}}} | preceding = {{{preceding12|}}} | preceded = {{{preceded12|}}} | premier = {{{premier12|}}} | president = {{{president12|}}} | primeminister = {{{primeminister12|}}} | riding = {{{riding12|}}} | state_assembly = {{{state_assembly12|}}} | state_delegate = {{{state_delegate12|}}} | state_house = {{{state_house12|}}} | state_legislature = {{{state_legislature12|}}} | state_senate = {{{state_senate12|}}} | state = {{{state12|}}} | status = {{{status12|}}} | subterm = {{{subterm12|}}} | suboffice = {{{suboffice12|}}} | succeeded = {{{succeeded12|}}} | succeeding = {{{succeeding12|}}} | successor = {{{successor12|}}} | taoiseach = {{{taoiseach12|}}} | termlabel = {{{term_label12|{{{termlabel12|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend12|}}}|{{{termend12}}}|{{{term_end12|}}}}} | termstart = {{#if:{{{termstart12|}}}|{{{termstart12}}}|{{{term_start12|}}}}} | term = {{{term12|}}} | title = {{{title12|}}} | vicegovernor = {{{vicegovernor12|}}} | vicepresident = {{{vicepresident12|}}} | vicepremier = {{{vicepremier12|}}} | viceprimeminister = {{{viceprimeminister12|}}} | party = {{{party|}}} | prior_term = {{{prior_term12|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname13|}}} | 1namedata = {{{1namedata13|}}} | 2blankname = {{{2blankname13|}}} | 2namedata = {{{2namedata13|}}} | 3blankname = {{{3blankname13|}}} | 3namedata = {{{3namedata13|}}} | 4blankname = {{{4blankname13|}}} | 4namedata = {{{4namedata13|}}} | 5blankname = {{{5blankname13|}}} | 5namedata = {{{5namedata13|}}} | alongside = {{{alongside13|}}} | ambassador_from = {{{ambassador_from13|}}} | appointer = {{#if: {{{appointer13|}}} | {{{appointer13}}} | {{{appointed13|}}} }} | assembly = {{{assembly13|}}} | assuming = {{{assuming13|}}} | chancellor = {{{chancellor13|}}} | co-leader = {{{co-leader13|}}} | constituency_{{#if:{{{constituency_AM13|}}}|AM|MP}} = {{#if: {{{constituency_AM13|}}} | {{{constituency_AM13}}} | {{{constituency_MP13|}}} }} | constituency = {{{constituency13|}}} | convocation = {{{convocation13|}}} | country = {{{country13|}}} | deputy = {{{deputy13|}}} | deputyminister = {{{deputyminister13|}}} | headminister = {{{headminister13|}}} | district = {{{district13|}}} | firstminister = {{{firstminister13|}}} | governor-general = {{{governor-general13|}}} | governor_general = {{{governor_general13|}}} | governor = {{{governor13|}}} | jr/sr = {{{jr/sr13|}}} | jr/sr and state = {{{jr/sr and state13|}}} | leader = {{{leader13|}}} | legislature = {{{legislature13|}}} | lieutenant_governor = {{{lieutenant_governor13|}}} | lieutenant = {{{lieutenant13|}}} | minister_from = {{{minister_from13|}}} | minority_floor_leader = {{{minority_floor_leader13|}}} | majority_floor_leader = {{{majority_floor_leader13|}}} | majority_leader = {{#if: {{{majorityleader13|}}} | {{{majorityleader13}}} | {{{majority_leader13|}}} }} | majority = {{{majority13|}}} | minister = {{{minister13|}}} | minority_leader = {{#if: {{{minorityleader13|}}} | {{{minorityleader13}}} | {{{minority_leader13|}}} }} | monarch = {{{monarch13|}}} | nominator = {{{nominator13|}}} | office = {{{office13|}}} | order = {{{order13|}}} | parliament = {{{parliament13|}}} | parliamentarygroup = {{{parliamentarygroup13|}}} | predecessor = {{{predecessor13|}}} | preceding = {{{preceding13|}}} | preceded = {{{preceded13|}}} | premier = {{{premier13|}}} | president = {{{president13|}}} | primeminister = {{{primeminister13|}}} | riding = {{{riding13|}}} | state_assembly = {{{state_assembly13|}}} | state_delegate = {{{state_delegate13|}}} | state_house = {{{state_house13|}}} | state_legislature = {{{state_legislature13|}}} | state_senate = {{{state_senate13|}}} | state = {{{state13|}}} | status = {{{status13|}}} | subterm = {{{subterm13|}}} | suboffice = {{{suboffice13|}}} | succeeded = {{{succeeded13|}}} | succeeding = {{{succeeding13|}}} | successor = {{{successor13|}}} | taoiseach = {{{taoiseach13|}}} | termlabel = {{{term_label13|{{{termlabel13|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend13|}}}|{{{termend13}}}|{{{term_end13|}}}}} | termstart = {{#if:{{{termstart13|}}}|{{{termstart13}}}|{{{term_start13|}}}}} | term = {{{term13|}}} | title = {{{title13|}}} | vicegovernor = {{{vicegovernor13|}}} | vicepresident = {{{vicepresident13|}}} | vicepremier = {{{vicepremier13|}}} | viceprimeminister = {{{viceprimeminister13|}}} | party = {{{party|}}} | prior_term = {{{prior_term13|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname14|}}} | 1namedata = {{{1namedata14|}}} | 2blankname = {{{2blankname14|}}} | 2namedata = {{{2namedata14|}}} | 3blankname = {{{3blankname14|}}} | 3namedata = {{{3namedata14|}}} | 4blankname = {{{4blankname14|}}} | 4namedata = {{{4namedata14|}}} | 5blankname = {{{5blankname14|}}} | 5namedata = {{{5namedata14|}}} | alongside = {{{alongside14|}}} | ambassador_from = {{{ambassador_from14|}}} | appointer = {{#if: {{{appointer14|}}} | {{{appointer14}}} | {{{appointed14|}}} }} | assembly = {{{assembly14|}}} | assuming = {{{assuming14|}}} | chancellor = {{{chancellor14|}}} | co-leader = {{{co-leader14|}}} | constituency_{{#if:{{{constituency_AM14|}}}|AM|MP}} = {{#if: {{{constituency_AM14|}}} | {{{constituency_AM14}}} | {{{constituency_MP14|}}} }} | constituency = {{{constituency14|}}} | convocation = {{{convocation14|}}} | country = {{{country14|}}} | deputy = {{{deputy14|}}} | deputyminister = {{{deputyminister14|}}} | headminister = {{{headminister14|}}} | district = {{{district14|}}} | firstminister = {{{firstminister14|}}} | governor-general = {{{governor-general14|}}} | governor_general = {{{governor_general14|}}} | governor = {{{governor14|}}} | jr/sr = {{{jr/sr14|}}} | jr/sr and state = {{{jr/sr and state14|}}} | leader = {{{leader14|}}} | legislature = {{{legislature14|}}} | lieutenant_governor = {{{lieutenant_governor14|}}} | lieutenant = {{{lieutenant14|}}} | minister_from = {{{minister_from14|}}} | minority_floor_leader = {{{minority_floor_leader14|}}} | majority_floor_leader = {{{majority_floor_leader14|}}} | majority_leader = {{#if: {{{majorityleader14|}}} | {{{majorityleader14}}} | {{{majority_leader14|}}} }} | majority = {{{majority14|}}} | minister = {{{minister14|}}} | minority_leader = {{#if: {{{minorityleader14|}}} | {{{minorityleader14}}} | {{{minority_leader14|}}} }} | monarch = {{{monarch14|}}} | nominator = {{{nominator14|}}} | office = {{{office14|}}} | order = {{{order14|}}} | parliament = {{{parliament14|}}} | parliamentarygroup = {{{parliamentarygroup14|}}} | predecessor = {{{predecessor14|}}} | preceding = {{{preceding14|}}} | preceded = {{{preceded14|}}} | premier = {{{premier14|}}} | president = {{{president14|}}} | primeminister = {{{primeminister14|}}} | riding = {{{riding14|}}} | state_assembly = {{{state_assembly14|}}} | state_delegate = {{{state_delegate14|}}} | state_house = {{{state_house14|}}} | state_legislature = {{{state_legislature14|}}} | state_senate = {{{state_senate14|}}} | state = {{{state14|}}} | status = {{{status14|}}} | subterm = {{{subterm14|}}} | suboffice = {{{suboffice14|}}} | succeeded = {{{succeeded14|}}} | succeeding = {{{succeeding14|}}} | successor = {{{successor14|}}} | taoiseach = {{{taoiseach14|}}} | termlabel = {{{term_label14|{{{termlabel14|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend14|}}}|{{{termend14}}}|{{{term_end14|}}}}} | termstart = {{#if:{{{termstart14|}}}|{{{termstart14}}}|{{{term_start14|}}}}} | term = {{{term14|}}} | title = {{{title14|}}} | vicegovernor = {{{vicegovernor14|}}} | vicepresident = {{{vicepresident14|}}} | vicepremier = {{{vicepremier14|}}} | viceprimeminister = {{{viceprimeminister14|}}} | party = {{{party|}}} | prior_term = {{{prior_term14|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname15|}}} | 1namedata = {{{1namedata15|}}} | 2blankname = {{{2blankname15|}}} | 2namedata = {{{2namedata15|}}} | 3blankname = {{{3blankname15|}}} | 3namedata = {{{3namedata15|}}} | 4blankname = {{{4blankname15|}}} | 4namedata = {{{4namedata15|}}} | 5blankname = {{{5blankname15|}}} | 5namedata = {{{5namedata15|}}} | alongside = {{{alongside15|}}} | ambassador_from = {{{ambassador_from15|}}} | appointer = {{#if: {{{appointer15|}}} | {{{appointer15}}} | {{{appointed15|}}} }} | assembly = {{{assembly15|}}} | assuming = {{{assuming15|}}} | chancellor = {{{chancellor15|}}} | co-leader = {{{co-leader15|}}} | constituency_{{#if:{{{constituency_AM15|}}}|AM|MP}} = {{#if: {{{constituency_AM15|}}} | {{{constituency_AM15}}} | {{{constituency_MP15|}}} }} | constituency = {{{constituency15|}}} | convocation = {{{convocation15|}}} | country = {{{country15|}}} | deputy = {{{deputy15|}}} | deputyminister = {{{deputyminister15|}}} | headminister = {{{headminister15|}}} | district = {{{district15|}}} | firstminister = {{{firstminister15|}}} | governor-general = {{{governor-general15|}}} | governor_general = {{{governor_general15|}}} | governor = {{{governor15|}}} | jr/sr = {{{jr/sr15|}}} | jr/sr and state = {{{jr/sr and state15|}}} | leader = {{{leader15|}}} | legislature = {{{legislature15|}}} | lieutenant_governor = {{{lieutenant_governor15|}}} | lieutenant = {{{lieutenant15|}}} | minister_from = {{{minister_from15|}}} | minority_floor_leader = {{{minority_floor_leader15|}}} | majority_floor_leader = {{{majority_floor_leader15|}}} | majority_leader = {{#if: {{{majorityleader15|}}} | {{{majorityleader15}}} | {{{majority_leader15|}}} }} | majority = {{{majority15|}}} | minister = {{{minister15|}}} | minority_leader = {{#if: {{{minorityleader15|}}} | {{{minorityleader15}}} | {{{minority_leader15|}}} }} | monarch = {{{monarch15|}}} | nominator = {{{nominator15|}}} | office = {{{office15|}}} | order = {{{order15|}}} | parliament = {{{parliament15|}}} | parliamentarygroup = {{{parliamentarygroup15|}}} | predecessor = {{{predecessor15|}}} | preceding = {{{preceding15|}}} | preceded = {{{preceded15|}}} | premier = {{{premier15|}}} | president = {{{president15|}}} | primeminister = {{{primeminister15|}}} | riding = {{{riding15|}}} | state_assembly = {{{state_assembly15|}}} | state_delegate = {{{state_delegate15|}}} | state_house = {{{state_house15|}}} | state_legislature = {{{state_legislature15|}}} | state_senate = {{{state_senate15|}}} | state = {{{state15|}}} | status = {{{status15|}}} | subterm = {{{subterm15|}}} | suboffice = {{{suboffice15|}}} | succeeded = {{{succeeded15|}}} | succeeding = {{{succeeding15|}}} | successor = {{{successor15|}}} | taoiseach = {{{taoiseach15|}}} | termlabel = {{{term_label15|{{{termlabel15|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend15|}}}|{{{termend15}}}|{{{term_end15|}}}}} | termstart = {{#if:{{{termstart15|}}}|{{{termstart15}}}|{{{term_start15|}}}}} | term = {{{term15|}}} | title = {{{title15|}}} | vicegovernor = {{{vicegovernor15|}}} | vicepresident = {{{vicepresident15|}}} | vicepremier = {{{vicepremier15|}}} | viceprimeminister = {{{viceprimeminister15|}}} | party = {{{party|}}} | prior_term = {{{prior_term15|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname16|}}} | 1namedata = {{{1namedata16|}}} | 2blankname = {{{2blankname16|}}} | 2namedata = {{{2namedata16|}}} | 3blankname = {{{3blankname16|}}} | 3namedata = {{{3namedata16|}}} | 4blankname = {{{4blankname16|}}} | 4namedata = {{{4namedata16|}}} | 5blankname = {{{5blankname16|}}} | 5namedata = {{{5namedata16|}}} | alongside = {{{alongside16|}}} | ambassador_from = {{{ambassador_from16|}}} | appointer = {{#if: {{{appointer16|}}} | {{{appointer16}}} | {{{appointed16|}}} }} | assembly = {{{assembly16|}}} | assuming = {{{assuming16|}}} | chancellor = {{{chancellor16|}}} | co-leader = {{{co-leader16|}}} | constituency_{{#if:{{{constituency_AM16|}}}|AM|MP}} = {{#if: {{{constituency_AM16|}}} | {{{constituency_AM16}}} | {{{constituency_MP16|}}} }} | constituency = {{{constituency16|}}} | convocation = {{{convocation16|}}} | country = {{{country16|}}} | deputy = {{{deputy16|}}} | deputyminister = {{{deputyminister16|}}} | headminister = {{{headminister16|}}} | district = {{{district16|}}} | firstminister = {{{firstminister16|}}} | governor-general = {{{governor-general16|}}} | governor_general = {{{governor_general16|}}} | governor = {{{governor16|}}} | jr/sr = {{{jr/sr16|}}} | jr/sr and state = {{{jr/sr and state16|}}} | leader = {{{leader16|}}} | legislature = {{{legislature16|}}} | lieutenant_governor = {{{lieutenant_governor16|}}} | lieutenant = {{{lieutenant16|}}} | minister_from = {{{minister_from16|}}} | minority_floor_leader = {{{minority_floor_leader16|}}} | majority_floor_leader = {{{majority_floor_leader16|}}} | majority_leader = {{#if: {{{majorityleader16|}}} | {{{majorityleader16}}} | {{{majority_leader16|}}} }} | majority = {{{majority16|}}} | minister = {{{minister16|}}} | minority_leader = {{#if: {{{minorityleader16|}}} | {{{minorityleader16}}} | {{{minority_leader16|}}} }} | monarch = {{{monarch16|}}} | nominator = {{{nominator16|}}} | office = {{{office16|}}} | order = {{{order16|}}} | parliament = {{{parliament16|}}} | parliamentarygroup = {{{parliamentarygroup16|}}} | predecessor = {{{predecessor16|}}} | preceding = {{{preceding16|}}} | preceded = {{{preceded16|}}} | premier = {{{premier16|}}} | president = {{{president16|}}} | primeminister = {{{primeminister16|}}} | riding = {{{riding16|}}} | state_assembly = {{{state_assembly16|}}} | state_delegate = {{{state_delegate16|}}} | state_house = {{{state_house16|}}} | state_legislature = {{{state_legislature16|}}} | state_senate = {{{state_senate16|}}} | state = {{{state16|}}} | status = {{{status16|}}} | subterm = {{{subterm16|}}} | suboffice = {{{suboffice16|}}} | succeeded = {{{succeeded16|}}} | succeeding = {{{succeeding16|}}} | successor = {{{successor16|}}} | taoiseach = {{{taoiseach16|}}} | termlabel = {{{term_label16|{{{termlabel16|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend16|}}}|{{{termend16}}}|{{{term_end16|}}}}} | termstart = {{#if:{{{termstart16|}}}|{{{termstart16}}}|{{{term_start16|}}}}} | term = {{{term16|}}} | title = {{{title16|}}} | vicegovernor = {{{vicegovernor16|}}} | vicepresident = {{{vicepresident16|}}} | vicepremier = {{{vicepremier16|}}} | viceprimeminister = {{{viceprimeminister16|}}} | party = {{{party|}}} | prior_term = {{{prior_term16|}}} }}}} | data2 = {{{module0|}}} <!----------Personal data----------> | header3 = {{#if:{{{pronunciation|}}}{{{birth_name|{{{birthname|}}}}}}{{{birth_date|}}}{{{birth_place|}}}{{{death_date|}}}{{{death_place|}}}{{{resting_place|{{{restingplace|}}}}}}{{{resting_place_coordinates|}}}{{{restingplacecoordinates|}}}{{{burial_place|}}}{{{citizenship|}}}{{{nationality|}}}{{{party|}}}{{{otherparty|}}}{{{spouse|}}}{{{spouses|}}}{{{spouse(s)|}}}{{{partner|}}}{{{relations|}}}{{{children|}}}{{{parents|}}}{{{mother|}}}{{{father|}}}{{{relatives|}}}{{{residence|}}}{{{education|}}}{{{alma_mater|}}}{{{occupation|}}}{{{profession|}}}{{{know for|}}}{{{know_for|}}}{{{known for|}}}{{{known_for|}}}{{{salary|}}}{{{cabinet|}}}{{{committees|}}}{{{portfolio|}}}{{{awards|}}}{{{data1|}}}{{{data2|}}}{{{data3|}}}{{{data4|}}}{{{data5|}}}|ข้อมูลส่วนบุคคล}} | label4 = เสียงอ่าน | data4 = {{{pronunciation|}}} | label5 = เกิด | data5 = {{br separated entries |1 = {{#if:{{{birth_name|{{{birthname|{{{birth name|}}}}}}}}}|<div style="display:inline" class="nickname">{{{birth_name|{{{birthname|{{{birth name}}}}}}}}}</div>}} |2 = {{{birth_date|}}} |3 = {{{birth_place|}}} }} | label6 = เสียชีวิต | data6 = {{br separated entries|{{{death_date|}}}|{{{death_place|}}}}} | label7 = {{#ifexpr: {{strfind short| {{{death_cause|}}}|ถูกลอบสังหาร}} | ลักษณะ |{{#if:{{{death_manner|}}}|ลักษณะ|สาเหตุ}} }}การเสียชีวิต | data7 = {{#if:{{{death_manner|}}}|{{{death_manner|}}}|{{{death_cause|}}}}} | label8 = ที่ไว้ศพ | class8 = label | data8 = {{br separated entries|{{{resting_place|{{{restingplace|{{{burial_place|}}} }}} }}}|{{{resting_place_coordinates|{{{restingplacecoordinates|{{{burial_place|}}} }}} }}}}} | label9 = สัญชาติ | data9 = {{{citizenship|}}} | label10 = เชื้อชาติ | data10 = {{#switch:{{Delink|{{{nationality|}}}}} | {{#ifeq:{{Country2nationality|{{Find country|{{Delink|{{{birth_place|}}}}}}}}}|{{Delink|{{{nationality|}}}}}|{{Delink|{{{nationality|}}}}}}} = | {{#ifeq:{{Find country|{{{birth_place|}}}}}|England|British}} = | #default = {{{nationality|}}} }} | label11 = ศาสนา | data11 = {{{religion|}}} | label12 = พรรคการเมือง | data12 = {{{party|}}} | label13 = {{nowrap|การเข้าร่วม}}<br />{{nowrap|พรรคการเมืองอื่น}} | data13 = {{{otherparty|{{{other_party|}}} }}} | label14 = ความสูง | data14 = {{#if:{{{height|{{{ส่วนสูง|{{{ความสูง|}}} }}} }}}|{{infobox person/height|{{{height|{{{ส่วนสูง|{{{ความสูง|}}} }}} }}}}}}} | label15 = คู่สมรส | data15 = {{{spouse|{{{spouses|{{{spouse(s)|}}}}}}}}} | label16 = คู่อาศัย | data16 = {{{partner|}}} | label17 = ญาติ | data17 = {{{relations|}}} | label18 = บุตร | data18 = {{{children|}}} | label19 = บุพการี | data19 = {{#if:{{{parents|}}}|{{{parents}}}|{{Unbulleted list|{{#if:{{{father|}}}|{{{father}}} (บิดา)}}|{{#if:{{{mother|}}}|{{{mother}}} (มารดา)}}}}}} | label20 = ความสัมพันธ์ | data20 = {{{relatives|}}} | label21 = ที่อยู่อาศัย | class21 = {{#if:{{{death_date|}}}{{{death_place|}}}||label}} | data21 = {{{residence|}}} | label22 = การศึกษา | data22 = {{{education|}}} | label23 = [[โรงเรียนแม่|ศิษย์เก่า]] | data23 = {{{alma_mater|}}} | label24 = อาชีพ | data24= {{{occupation|}}} | label25 = วิชาชีพ | data25 = {{{profession|}}} | label26 = เป็นที่รู้จักจาก | data26 = {{{know for|{{{know_for|{{{known for|{{{known_for|}}} }}} }}} }}} | label27 = เงินเดือน | data27 = {{{salary|}}} | label28 = ทรัพย์สินสุทธิ | data28 = {{{net_worth|}}} | label29 = รัฐบาล | data29 = {{{cabinet|}}} | label30 = คณะกรรมาธิการ | data30 = {{{committees|}}} | label31 = ผลงานเด่น | data31 = {{{portfolio|}}} | label32 = {{#if:{{{mawards|}}}|บำนาญ|รางวัล}} | data32 = {{{awards|}}} | label33 = {{{blank1}}} | data33 = {{{data1|}}} | label34 = {{{blank2}}} | data34 = {{{data2|}}} | label35 = {{{blank3}}} | data35 = {{{data3|}}} | label36 = {{{blank4}}} | data36 = {{{data4|}}} | label37 = {{{blank5}}} | data37 = {{{data5|}}} | label38 = ลายมือชื่อ | data38 = {{#if:{{{signature|}}}|[[File:{{{signature}}}|{{#if:{{{signature_size|}}}|{{{signature_size}}}|128x80px}}|alt={{{signature_alt|}}}|ลายมือชื่อของ{{PAGENAME}}]]}} | label39 = เว็บไซต์ | data39 = {{{website|{{{homepage|}}} }}} | label40 = ชื่อเล่น | data40 = {{{nickname|{{{other_names|{{{othernames|{{{othername|{{{nicknames|}}} }}} }}} }}} }}} | header41 = {{#if:{{{allegiance|}}}{{{branch|}}}{{{serviceyears|}}}{{{rank|}}}{{{unit|}}}{{{commands|}}}{{{battles|}}}{{{wars|}}}{{{battles/wars|}}}{{{military_blank1|}}}|ยศที่ได้รับการแต่งตั้ง}} | label42 = รับใช้ | data42 = {{{allegiance|}}} | label43 = {{#if:{{{branch_label|}}}|{{{branch_label|}}}|สังกัด}} | data43 = {{{branch|}}} | label44 = {{#if:{{{serviceyears_label|}}}|{{{serviceyears_label|}}}|ประจำการ}} | data44 = {{{serviceyears|}}} | label45 = {{#if:{{{rank_label|}}}|{{{rank_label|}}}|ยศ}} | data45 = {{{rank|}}} | label46 = {{#if:{{{unit_label|}}}|{{{unit_label|}}}|หน่วย}} | data46 = {{{unit|}}} | label47 = บังคับบัญชา | data47 = {{{commands|}}} | label48 = {{#if:{{{battles_label|}}}|{{{battles_label|}}}|สงคราม/การสู้รบ}} | data48 = {{{battles|{{{wars|{{{battles/wars|}}} }}} }}} | label49 = {{#if:{{{awards|}}}|บำเหน็จ|รางวัล}} | data49 = {{{mawards|}}} | label50 = {{{military_blank1}}} | data50 = {{{military_data1|}}} | label51 = {{{military_blank2}}} | data51 = {{{military_data2|}}} | label52 = {{{military_blank3}}} | data52 = {{{military_data3|}}} | label53 = {{{military_blank4}}} | data53 = {{{military_data4|}}} | label54 = {{{military_blank5}}} | data54 = {{{military_data5|}}} | data55 = {{{module|}}} | data56 = {{{module2|}}} | data57 = {{{module3|}}} | data58 = {{{module4|}}} | data59 = {{{module5|}}} | data60 = {{{footnotes|}}} | belowstyle = border-top: 1px solid right; font-size: 95% | below = <div>{{#if:{{{date|}}}| ณ วันที่ {{{date}}}{{#if:{{{year|}}}|, {{{year}}}}}}}</div>{{#if:{{{source|}}}|ที่มา: [{{{source}}}]}} }}{{#if:{{{pronunciation|}}}|{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[Category:Biography template using pronunciation]]}} }}{{#if:{{{1blankname0|}}}{{{1namedata0|}}}{{{2blankname0|}}}{{{2namedata0|}}}{{{3blankname0|}}}{{{3namedata0|}}}{{{4blankname0|}}}{{{4namedata0|}}}{{{5blankname0|}}}{{{5namedata0|}}}{{{alongside0|}}}{{{ambassador_from0|}}}{{{appointer0|}}}{{{assembly0|}}}{{{assuming0|}}}{{{chancellor0|}}}{{{co-leader0|}}}{{{constituency_AM0|}}}{{{constituency0|}}}{{{country0|}}}{{{deputy0|}}}{{{district0|}}}{{{firstminister0|}}}{{{governor-general0|}}}{{{governor0|}}}{{{jr/sr0|}}}{{{jr/sr and state0|}}}{{{leader0|}}}{{{legislature0|}}}{{{lieutenant_governor0|}}}{{{lieutenant0|}}}{{{minister_from0|}}}{{{minority_floor_leader0|}}}{{{majority_floor_leader0|}}}{{{majorityleader0|}}}{{{majority0|}}}{{{minister0|}}}{{{minorityleader0|}}}{{{monarch0|}}}{{{nominator0|}}}{{{office0|}}}{{{order0|}}}{{{parliament0|}}}{{{predecessor0|}}}{{{preceding0|}}}{{{preceded0|}}}{{{premier0|}}}{{{president0|}}}{{{primeminister0|}}}{{{riding0|}}}{{{state_assembly0|}}}{{{state_delegate0|}}}{{{state_house0|}}}{{{state_legislature0|}}}{{{state_senate0|}}}{{{state0|}}}{{{suboffice0|}}}{{{subterm0|}}}{{{succeeded0|}}}{{{succeeding0|}}}{{{successor0|}}}{{{taoiseach0|}}}{{{termend0|}}}{{{termstart0|}}}{{{term0|}}}{{{title0|}}}{{{vicegovernor0|}}}{{{vicepresident0|}}}{{{vicepremier0|}}}{{{viceprimeminister0|}}}{{{prior_term0|}}}{{{appointe0|}}}{{{constituency_0|}}}|{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[Category:Pages using infobox officeholder with office0]]}} }}{{#if:{{{speaker|}}}|{{#if:{{{nominee|}}}{{{candidate|}}}||{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[Category:Pages using infobox officeholder with speaker]]}}}} }}{{#invoke:Check for unknown parameters|check|unknown={{main other|{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[หมวดหมู่:หน้าที่ใช้กล่องข้อมูลผู้ดำรงตำแหน่งที่มีพารามิเตอร์ที่ไม่รู้จัก|_VALUE_{{PAGENAME}}]]}}}}|preview=หน้านี้ใช้ [[แม่แบบ:กล่องข้อมูล ผู้ดำรงตำแหน่ง]] ที่มีพารามิเตอร์ที่ไม่รู้จัก "_VALUE_"|ignoreblank=y| regexp1 = 1blankname[%d]* | regexp2 = 1namedata[%d]* | regexp3 = 2blankname[%d]* | regexp4 = 2namedata[%d]* | regexp5 = 3blankname[%d]* | regexp6 = 3namedata[%d]* | regexp7 = 4blankname[%d]* | regexp8 = 4namedata[%d]* | regexp9 = 5blankname[%d]* | regexp10 = 5namedata[%d]* | allegiance | alma_mater | regexp11 = alongside[%d]* | alt | regexp12 = ambassador_from[%d]* | regexp13 = appointed[%d]* | regexp14 = appointer[%d]* | regexp15 = assembly[%d]* | awards | battles | battles/wars | battles_label | birth_date | birth name | birth_name | birth_place | birthname | regexp16 = blank[%d]* | bodyclass | branch | branch_label | burial_place | cabinet | candidate | caption | categories | regexp17 = chancellor[%d]* | children | citizenship | regexp18 = co%-leader[%d]* | commands | committees | regexp19 = constituency[%d]* | regexp20 = constituency_AM[%d]* | regexp21 = constituency_MP[%d]* | regexp22 = convocation[%d]* | regexp23 = country[%d]* | regexp24 = data[%d]* | date | death_cause | death_date | death_manner | death_place | demo | regexp25 = deputy[%d]* | regexp26 = deputyminister[%d]* | regexp27 = district[%d]* | education | election_date | embed | father | regexp28 = firstminister[%d]* | footnotes | regexp29 = governor[%d]* | regexp30 = governor_general[%d]* | regexp31 = governor%-general[%d]* | regexp32 = headminister[%d]* | height | homepage | honorific_prefix | honorific-prefix | honorific_suffix | honorific-suffix | image | image name | image_name_alt | image_size | imagesize | image_upright | incumbent | regexp33 = jr/sr[%d]* | regexp34 = jr/sr and state[%d]* | know for | know_for | known for | known_for | regexp35 = leader[%d]* | regexp36 = legislature[%d]* | regexp37 = lieutenant[%d]* | regexp38 = lieutenant_governor[%d]* | mainwidth | regexp39 = majority[%d]* | regexp40 = majority_floor_leader[%d]* | regexp41 = majority_leader[%d]* | regexp42 = majorityleader[%d]* | mawards | regexp43 = military_blank[%d]* | regexp44 = military_data[%d]* | regexp45 = minister[%d]* | regexp46 = minister_from[%d]* | regexp47 = minority_floor_leader[%d]* | regexp48 = minority_leader[%d]* | regexp49 = minorityleader[%d]* | regexp50 = module[%d]* | regexp51 = monarch[%d]* | mother | name | nationality | native_name | native_name_lang | net_worth | nickname | nicknames | nocat | regexp52 = nominator[%d]* | nominee | occupation | regexp53 = office[%d]* | opponent | regexp54 = order[%d]* | othername | othernames | other_names | otherparty | other_party | parents | regexp55 = parliament[%d]* | regexp56 = parliamentarygroup[%d]* | partner | party | party_election | portfolio | regexp57 = preceded[%d]* | regexp58 = preceding[%d]* | regexp59 = predecessor[%d]* | regexp60 = premier[%d]* | regexp61 = president[%d]* | regexp62 = primeminister[%d]* | regexp63 = prior_term[%d]* | profession | pronunciation | rank | rank_label | relations | relatives | religion | residence | resting_place | resting_place_coordinates | restingplace | restingplacecoordinates | regexp64 = riding[%d]* | runningmate | salary | serviceyears | serviceyears_label | signature | signature_alt | signature_size | smallimage | smallimage_alt | source | speaker | speaker_office | spouse | spouses | spouse(s) | regexp65 = state[%d]* | regexp66 = state_assembly[%d]* | regexp67 = state_delegate[%d]* | regexp68 = state_house[%d]* | regexp69 = state_legislature[%d]* | regexp70 = state_senate[%d]* | regexp71 = status[%d]* | regexp72 = suboffice[%d]* | regexp73 = subterm[%d]* | regexp74 = succeeded[%d]* | regexp75 = succeeding[%d]* | regexp76 = successor[%d]* | regexp77 = taoiseach[%d]* | regexp78 = term[%d]* | regexp79 = term_end[%d]* | regexp80 = term_label[%d]* | regexp81 = term_start[%d]* | regexp82 = termend[%d]* | regexp83 = termlabel[%d]* | regexp84 = termstart[%d]* | regexp85 = title[%d]* | unit | unit_label | regexp86 = vicegovernor[%d]* | regexp87 = vicepremier[%d]* | regexp88 = vicepresident[%d]* | regexp89 = viceprimeminister[%d]* | regexp90 = assuming[%d]* | wars | website | width | year | ความสูง | ส่วนสูง }}<noinclude> {{คู่มือการใช้งาน}} </noinclude> cefce0a0af2f82f5ebcbe9ed766e048d61f4e31e 47 46 2023-10-05T11:35:53Z PeachFullzZ 2 wikitext text/x-wiki {{#invoke:infobox|infoboxTemplate | bodyclass = vcard {{{bodyclass|}}} | bodystyle = {{#if:{{{mainwidth|}}}|width: {{{mainwidth}}}}} | child = {{lc:{{{embed}}}}} | abovestyle = font-size: 100%; | above = {{#if:{{{honorific prefix|{{{honorific_prefix|{{{honorific-prefix|}}}}}}}}}|<div class="honorific-prefix" style="font-weight: normal;">{{{honorific prefix|{{{honorific_prefix|{{{honorific-prefix}}}}}}}}}</div>}}<!-- --><div class="fn" style="font-size:125%;">{{#if:{{{name|}}}|{{{name}}}|{{PAGENAMEBASE}}}}</div><!-- -->{{#if:{{{honorific suffix|{{{honorific_suffix|{{{honorific-suffix|}}}}}}}}}|<div class="honorific-suffix" style="font-weight: normal;">{{{honorific suffix|{{{honorific_suffix|{{{honorific-suffix}}}}}}}}}</div>}} | subheaderstyle = font-size:125%; font-weight:bold; | subheader = {{#ifeq:{{lc:{{{embed}}}}}|yes||(@{{#if:{{{roblox_username|}}}|{{{roblox_username}}}}})}} | image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{{width|{{{imagesize|{{{image_size|}}}}}}}}}|sizedefault=frameless|upright={{{image_upright|1}}}|alt={{{alt|}}}|suppressplaceholder=yes}} | image2 = {{#invoke:InfoboxImage|InfoboxImage|image={{{image name|}}}|size={{{width|{{{imagesize|{{{image_size|}}}}}}}}}|sizedefault=frameless|upright={{{image_upright|1}}}|alt={{{image_name_alt|}}}|suppressplaceholder=yes}} | image3 = {{#invoke:InfoboxImage|InfoboxImage|image={{{smallimage|}}}|sizedefault=frameless|upright={{{image_upright|1}}}|alt={{{smallimage_alt|}}}|suppressplaceholder=yes}} | captionstyle = line-height:normal;padding-top:0.2em; | caption{{#if:{{{smallimage|}}}|3|{{#if:{{{image name|}}}|2}}}} = {{{caption|}}} | headerstyle = {{#ifeq:{{lc:{{{embed}}}}}|yes|background:#eee|background:lavender}} | data1 = {{#if:{{{speaker|}}}| {{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname2|}}} | 1namedata = {{{1namedata2|}}} | 2blankname = {{{2blankname2|}}} | 2namedata = {{{2namedata2|}}} | 3blankname = {{{3blankname2|}}} | 3namedata = {{{3namedata2|}}} | 4blankname = {{{4blankname2|}}} | 4namedata = {{{4namedata2|}}} | 5blankname = {{{5blankname2|}}} | 5namedata = {{{5namedata2|}}} | alongside = {{{alongside2|}}} | ambassador_from = {{{ambassador_from2|}}} | appointer = {{#if: {{{appointer2|}}} | {{{appointer2}}} | {{{appointed2|}}} }} | assembly = {{{assembly2|}}} | assuming = {{{assuming2|}}} | chancellor = {{{chancellor2|}}} | co-leader = {{{co-leader2|}}} | constituency_{{#if:{{{constituency_AM2|}}}|AM|MP}} = {{#if: {{{constituency_AM2|}}} | {{{constituency_AM2}}} | {{{constituency_MP2|}}} }} | constituency = {{{constituency2|}}} | convocation = {{{convocation2|}}} | country = {{{country2|}}} | deputy = {{{deputy2|}}} | deputyminister = {{{deputyminister2|}}} | headminister = {{{headminister2|}}} | district = {{{district2|}}} | firstminister = {{{firstminister2|}}} | governor-general = {{{governor-general2|}}} | governor_general = {{{governor_general2|}}} | governor = {{{governor2|}}} | jr/sr = {{{jr/sr2|}}} | jr/sr and state = {{{jr/sr and state2|}}} | leader = {{{leader2|}}} | legislature = {{{legislature2|}}} | lieutenant_governor = {{{lieutenant_governor2|}}} | lieutenant = {{{lieutenant2|}}} | majority_leader = {{#if: {{{majorityleader2|}}} | {{{majorityleader2}}} | {{{majority_leader2|}}} }} | minister_from = {{{minister_from2|}}} | minority_floor_leader = {{{minority_floor_leader2|}}} | majority_floor_leader = {{{majority_floor_leader2|}}} | majority = {{{majority2|}}} | minister = {{{minister2|}}} | minority_leader = {{#if: {{{minorityleader2|}}} | {{{minorityleader2}}} | {{{minority_leader2|}}} }} | monarch = {{{monarch2|}}} | nominator = {{{nominator2|}}} | office = {{{office2|}}} | order = {{{order2|}}} | parliament = {{{parliament2|}}} | parliamentarygroup = {{{parliamentarygroup2|}}} | predecessor = {{{predecessor2|}}} | preceding = {{{preceding2|}}} | preceded = {{{preceded2|}}} | premier = {{{premier2|}}} | president = {{{president2|}}} | primeminister = {{{primeminister2|}}} | riding = {{{riding2|}}} | speaker = {{{speaker|}}} | speaker_office = {{{speaker_office|}}} | state_assembly = {{{state_assembly|}}} | state_delegate = {{{state_delegate|}}} | state_house = {{{state_house|}}} | state_legislature = {{{state_legislature|}}} | state_senate = {{{state_senate|}}} | state = {{{state|}}} | subterm = {{{subterm|}}} | suboffice = {{{suboffice|}}} | succeeded = {{{succeeded2|}}} | succeeding = {{{succeeding2|}}} | successor = {{{successor2|}}} | taoiseach = {{{taoiseach2|}}} | termlabel = {{{term_label2|{{{termlabel2|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend2|}}}|{{{termend2}}}|{{{term_end2|}}}}} | termstart = {{#if:{{{termstart2|}}}|{{{termstart2}}}|{{{term_start2|}}}}} | term = {{{term2|}}} | title = {{{title2|}}} | vicegovernor = {{{vicegovernor2|}}} | vicepresident = {{{vicepresident2|}}} | vicepremier = {{{vicepremier2|}}} | viceprimeminister = {{{viceprimeminister2|}}} | party = {{{party|}}} | prior_term = {{{prior_term|}}} }}}}}}<!-- -->{{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname|}}} | 1namedata = {{{1namedata|}}} | 2blankname = {{{2blankname|}}} | 2namedata = {{{2namedata|}}} | 3blankname = {{{3blankname|}}} | 3namedata = {{{3namedata|}}} | 4blankname = {{{4blankname|}}} | 4namedata = {{{4namedata|}}} | 5blankname = {{{5blankname|}}} | 5namedata = {{{5namedata|}}} | alongside = {{{alongside|}}} | ambassador_from = {{{ambassador_from|}}} | appointer = {{#if: {{{appointer|}}} | {{{appointer}}} | {{{appointed|}}} }} | assembly = {{{assembly|}}} | assuming = {{{assuming|}}} | candidate = {{{candidate|}}} | chancellor = {{{chancellor|}}} | co-leader = {{{co-leader|}}} | constituency_{{#if:{{{constituency_AM|}}}|AM|MP}} = {{#if: {{{constituency_AM|}}} | {{{constituency_AM}}} | {{{constituency_MP|}}} }} | constituency = {{{constituency|}}} | convocation = {{{convocation|}}} | country = {{{country|}}} | deputy = {{{deputy|}}} | deputyminister = {{{deputyminister|}}} | headminister = {{{headminister|}}} | district = {{{district|}}} | election_date = {{{election_date|}}} | firstminister = {{{firstminister|}}} | governor-general = {{{governor-general|}}} | governor_general = {{{governor_general|}}} | governor = {{{governor|}}} | incumbent = {{{incumbent|}}} | jr/sr = {{{jr/sr|}}} | jr/sr and state = {{{jr/sr and state|}}} | leader = {{{leader|}}} | legislature = {{{legislature|}}} | lieutenant_governor = {{{lieutenant_governor|}}} | lieutenant = {{{lieutenant|}}} | majority_leader = {{#if: {{{majorityleader|}}} | {{{majorityleader}}} | {{{majority_leader|}}} }} | majority = {{{majority|}}} | minister = {{{minister|}}} | minister_from = {{{minister_from|}}} | minority_floor_leader = {{{minority_floor_leader|}}} | majority_floor_leader = {{{majority_floor_leader|}}} | minority_leader = {{#if: {{{minorityleader|}}} | {{{minorityleader}}} | {{{minority_leader|}}} }} | monarch = {{{monarch|}}} | nominator = {{{nominator|}}} | nominee = {{{nominee|}}} | office = {{{office|}}} | opponent = {{{opponent|}}} | order = {{{order|}}} | parliament = {{{parliament|}}} | parliamentarygroup = {{{parliamentarygroup|}}} | party_election = {{{party_election|}}} | predecessor = {{{predecessor|}}} | preceding = {{{preceding|}}} | preceded = {{{preceded|}}} | premier = {{{premier|}}} | president = {{{president|}}} | primeminister = {{{primeminister|}}} | riding = {{{riding|}}} | runningmate = {{{runningmate|}}} | state_assembly = {{{state_assembly|}}} | state_delegate = {{{state_delegate|}}} | state_house = {{{state_house|}}} | state_legislature = {{{state_legislature|}}} | state_senate = {{{state_senate|}}} | state = {{{state|}}} | status = {{{status|}}} | suboffice = {{{suboffice|}}} | subterm = {{{subterm|}}} | succeeded = {{{succeeded|}}} | succeeding = {{{succeeding|}}} | successor = {{{successor|}}} | taoiseach = {{{taoiseach|}}} | termlabel = {{{term_label|{{{termlabel|ดำรงตำแหน่ง}}}}}} | termend = {{#if: {{{termend|}}} | {{{termend}}} | {{{term_end|}}} }} | termstart = {{#if: {{{termstart|}}} | {{{termstart}}} | {{{term_start|}}} }} | term = {{{term|}}} | title = {{{title|}}} | vicegovernor = {{{vicegovernor|}}} | vicepresident = {{{vicepresident|}}} | vicepremier = {{{vicepremier|}}} | viceprimeminister = {{{viceprimeminister|}}} | party = {{{party|}}} | prior_term = {{{prior_term|}}} }}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname1|}}} | 1namedata = {{{1namedata1|}}} | 2blankname = {{{2blankname1|}}} | 2namedata = {{{2namedata1|}}} | 3blankname = {{{3blankname1|}}} | 3namedata = {{{3namedata1|}}} | 4blankname = {{{4blankname1|}}} | 4namedata = {{{4namedata1|}}} | 5blankname = {{{5blankname1|}}} | 5namedata = {{{5namedata1|}}} | alongside = {{{alongside1|}}} | ambassador_from = {{{ambassador_from1|}}} | appointer = {{#if: {{{appointer1|}}} | {{{appointer1}}} | {{{appointed1|}}} }} | assembly = {{{assembly1|}}} | assuming = {{{assuming1|}}} | chancellor = {{{chancellor1|}}} | co-leader = {{{co-leader1|}}} | constituency_{{#if:{{{constituency_AM1|}}}|AM|MP}} = {{#if: {{{constituency_AM1|}}} | {{{constituency_AM1}}} | {{{constituency_MP1|}}} }} | constituency = {{{constituency1|}}} | convocation = {{{convocation1|}}} | country = {{{country1|}}} | deputy = {{{deputy1|}}} | deputyminister = {{{deputyminister1|}}} | headminister = {{{headminister1|}}} | district = {{{district1|}}} | firstminister = {{{firstminister1|}}} | governor-general = {{{governor-general1|}}} | governor_general = {{{governor_general1|}}} | governor = {{{governor1|}}} | jr/sr = {{{jr/sr1|}}} | jr/sr and state = {{{jr/sr and state1|}}} | leader = {{{leader1|}}} | legislature = {{{legislature1|}}} | lieutenant_governor = {{{lieutenant_governor1|}}} | lieutenant = {{{lieutenant1|}}} | minority_floor_leader = {{{minority_floor_leader1|}}} | minister_from = {{{minister_from1|}}} | majority_floor_leader = {{{majority_floor_leader1|}}} | majority_leader = {{#if: {{{majorityleader1|}}} | {{{majorityleader1}}} | {{{majority_leader1|}}} }} | majority = {{{majority1|}}} | minister = {{{minister1|}}} | minority_leader = {{#if: {{{minorityleader1|}}} | {{{minorityleader1}}} | {{{minority_leader1|}}} }} | monarch = {{{monarch1|}}} | nominator = {{{nominator1|}}} | office = {{{office1|}}} | order = {{{order1|}}} | parliament = {{{parliament1|}}} | parliamentarygroup = {{{parliamentarygroup1|}}} | predecessor = {{{predecessor1|}}} | preceding = {{{preceding1|}}} | preceded = {{{preceded1|}}} | premier = {{{premier1|}}} | president = {{{president1|}}} | primeminister = {{{primeminister1|}}} | riding = {{{riding1|}}} | state_assembly = {{{state_assembly1|}}} | state_delegate = {{{state_delegate1|}}} | state_house = {{{state_house1|}}} | state_legislature = {{{state_legislature1|}}} | state_senate = {{{state_senate1|}}} | state = {{{state1|}}} | status = {{{status1|}}} | subterm = {{{subterm1|}}} | suboffice = {{{suboffice1|}}} | succeeded = {{{succeeded1|}}} | succeeding = {{{succeeding1|}}} | successor = {{{successor1|}}} | taoiseach = {{{taoiseach1|}}} | termlabel = {{{term_label1|{{{termlabel1|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend1|}}}|{{{termend1}}}|{{{term_end1|}}}}} | termstart = {{#if:{{{termstart1|}}}|{{{termstart1}}}|{{{term_start1|}}}}} | term = {{{term1|}}} | title = {{{title1|}}} | vicegovernor = {{{vicegovernor1|}}} | vicepresident = {{{vicepresident1|}}} | vicepremier = {{{vicepremier1|}}} | viceprimeminister = {{{viceprimeminister1|}}} | party = {{{party|}}} | prior_term = {{{prior_term1|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{#if:{{{speaker|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname2|}}} | 1namedata = {{{1namedata2|}}} | 2blankname = {{{2blankname2|}}} | 2namedata = {{{2namedata2|}}} | 3blankname = {{{3blankname2|}}} | 3namedata = {{{3namedata2|}}} | 4blankname = {{{4blankname2|}}} | 4namedata = {{{4namedata2|}}} | 5blankname = {{{5blankname2|}}} | 5namedata = {{{5namedata2|}}} | alongside = {{{alongside2|}}} | ambassador_from = {{{ambassador_from2|}}} | appointer = {{#if: {{{appointer2|}}} | {{{appointer2}}} | {{{appointed2|}}} }} | assembly = {{{assembly2|}}} | assuming = {{{assuming2|}}} | chancellor = {{{chancellor2|}}} | co-leader = {{{co-leader2|}}} | constituency_{{#if:{{{constituency_AM2|}}}|AM|MP}} = {{#if: {{{constituency_AM2|}}} | {{{constituency_AM2}}} | {{{constituency_MP2|}}} }} | constituency = {{{constituency2|}}} | convocation = {{{convocation2|}}} | country = {{{country2|}}} | deputy = {{{deputy2|}}} | deputyminister = {{{deputyminister2|}}} | headminister = {{{headminister2|}}} | district = {{{district2|}}} | firstminister = {{{firstminister2|}}} | governor-general = {{{governor-general2|}}} | governor_general = {{{governor_general2|}}} | governor = {{{governor2|}}} | jr/sr = {{{jr/sr2|}}} | jr/sr and state = {{{jr/sr and state2|}}} | leader = {{{leader2|}}} | legislature = {{{legislature2|}}} | lieutenant_governor = {{{lieutenant_governor2|}}} | lieutenant = {{{lieutenant2|}}} | majority_leader = {{#if: {{{majorityleader2|}}} | {{{majorityleader2}}} | {{{majority_leader2|}}} }} | minister_from = {{{minister_from2|}}} | minority_floor_leader = {{{minority_floor_leader2|}}} | majority_floor_leader = {{{majority_floor_leader2|}}} | majority = {{{majority2|}}} | minister = {{{minister2|}}} | minority_leader = {{#if: {{{minorityleader2|}}} | {{{minorityleader2}}} | {{{minority_leader2|}}} }} | monarch = {{{monarch2|}}} | nominator = {{{nominator2|}}} | office = {{{office2|}}} | order = {{{order2|}}} | parliament = {{{parliament2|}}} | parliamentarygroup = {{{parliamentarygroup2|}}} | predecessor = {{{predecessor2|}}} | preceding = {{{preceding2|}}} | preceded = {{{preceded2|}}} | premier = {{{premier2|}}} | president = {{{president2|}}} | primeminister = {{{primeminister2|}}} | riding = {{{riding2|}}} | state_assembly = {{{state_assembly2|}}} | state_delegate = {{{state_delegate2|}}} | state_house = {{{state_house2|}}} | state_legislature = {{{state_legislature2|}}} | state_senate = {{{state_senate2|}}} | state = {{{state2|}}} | status = {{{status2|}}} | subterm = {{{subterm2|}}} | suboffice = {{{suboffice2|}}} | succeeded = {{{succeeded2|}}} | succeeding = {{{succeeding2|}}} | successor = {{{successor2|}}} | taoiseach = {{{taoiseach2|}}} | termlabel = {{{term_label2|{{{termlabel2|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend2|}}}|{{{termend2}}}|{{{term_end2|}}}}} | termstart = {{#if:{{{termstart2|}}}|{{{termstart2}}}|{{{term_start2|}}}}} | term = {{{term2|}}} | title = {{{title2|}}} | vicegovernor = {{{vicegovernor2|}}} | vicepresident = {{{vicepresident2|}}} | vicepremier = {{{vicepremier2|}}} | viceprimeminister = {{{viceprimeminister2|}}} | party = {{{party|}}} | prior_term = {{{prior_term2|}}} }}}}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname3|}}} | 1namedata = {{{1namedata3|}}} | 2blankname = {{{2blankname3|}}} | 2namedata = {{{2namedata3|}}} | 3blankname = {{{3blankname3|}}} | 3namedata = {{{3namedata3|}}} | 4blankname = {{{4blankname3|}}} | 4namedata = {{{4namedata3|}}} | 5blankname = {{{5blankname3|}}} | 5namedata = {{{5namedata3|}}} | alongside = {{{alongside3|}}} | ambassador_from = {{{ambassador_from3|}}} | appointer = {{#if: {{{appointer3|}}} | {{{appointer3}}} | {{{appointed3|}}} }} | assembly = {{{assembly3|}}} | assuming = {{{assuming3|}}} | chancellor = {{{chancellor3|}}} | co-leader = {{{co-leader3|}}} | constituency_{{#if:{{{constituency_AM3|}}}|AM|MP}} = {{#if: {{{constituency_AM3|}}} | {{{constituency_AM3}}} | {{{constituency_MP3|}}} }} | constituency = {{{constituency3|}}} | convocation = {{{convocation3|}}} | country = {{{country3|}}} | deputy = {{{deputy3|}}} | deputyminister = {{{deputyminister3|}}} | headminister = {{{headminister3|}}} | district = {{{district3|}}} | firstminister = {{{firstminister3|}}} | governor-general = {{{governor-general3|}}} | governor_general = {{{governor_general3|}}} | governor = {{{governor3|}}} | jr/sr = {{{jr/sr3|}}} | jr/sr and state = {{{jr/sr and state3|}}} | leader = {{{leader3|}}} | legislature = {{{legislature3|}}} | lieutenant_governor = {{{lieutenant_governor3|}}} | lieutenant = {{{lieutenant3|}}} | minority_floor_leader = {{{minority_floor_leader3|}}} | minister_from = {{{minister_from3|}}} | majority_floor_leader = {{{majority_floor_leader3|}}} | majority_leader = {{#if: {{{majorityleader3|}}} | {{{majorityleader3}}} | {{{majority_leader3|}}} }} | majority = {{{majority3|}}} | minister = {{{minister3|}}} | minority_leader = {{#if: {{{minorityleader3|}}} | {{{minorityleader3}}} | {{{minority_leader3|}}} }} | monarch = {{{monarch3|}}} | nominator = {{{nominator3|}}} | office = {{{office3|}}} | order = {{{order3|}}} | parliament = {{{parliament3|}}} | parliamentarygroup = {{{parliamentarygroup3|}}} | predecessor = {{{predecessor3|}}} | preceding = {{{preceding3|}}} | preceded = {{{preceded3|}}} | premier = {{{premier3|}}} | president = {{{president3|}}} | primeminister = {{{primeminister3|}}} | riding = {{{riding3|}}} | state_assembly = {{{state_assembly3|}}} | state_delegate = {{{state_delegate3|}}} | state_house = {{{state_house3|}}} | state_legislature = {{{state_legislature3|}}} | state_senate = {{{state_senate3|}}} | state = {{{state3|}}} | status = {{{status3|}}} | subterm = {{{subterm3|}}} | suboffice = {{{suboffice3|}}} | succeeded = {{{succeeded3|}}} | succeeding = {{{succeeding3|}}} | successor = {{{successor3|}}} | taoiseach = {{{taoiseach3|}}} | termlabel = {{{term_label3|{{{termlabel3|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend3|}}}|{{{termend3}}}|{{{term_end3|}}}}} | termstart = {{#if:{{{termstart3|}}}|{{{termstart3}}}|{{{term_start3|}}}}} | term = {{{term3|}}} | title = {{{title3|}}} | vicegovernor = {{{vicegovernor3|}}} | vicepresident = {{{vicepresident3|}}} | vicepremier = {{{vicepremier3|}}} | viceprimeminister = {{{viceprimeminister3|}}} | party = {{{party|}}} | prior_term = {{{prior_term3|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname4|}}} | 1namedata = {{{1namedata4|}}} | 2blankname = {{{2blankname4|}}} | 2namedata = {{{2namedata4|}}} | 3blankname = {{{3blankname4|}}} | 3namedata = {{{3namedata4|}}} | 4blankname = {{{4blankname4|}}} | 4namedata = {{{4namedata4|}}} | 5blankname = {{{5blankname4|}}} | 5namedata = {{{5namedata4|}}} | alongside = {{{alongside4|}}} | ambassador_from = {{{ambassador_from4|}}} | appointer = {{#if: {{{appointer4|}}} | {{{appointer4}}} | {{{appointed4|}}} }} | assembly = {{{assembly4|}}} | assuming = {{{assuming4|}}} | chancellor = {{{chancellor4|}}} | co-leader = {{{co-leader4|}}} | constituency_{{#if:{{{constituency_AM4|}}}|AM|MP}} = {{#if: {{{constituency_AM4|}}} | {{{constituency_AM4}}} | {{{constituency_MP4|}}} }} | constituency = {{{constituency4|}}} | convocation = {{{convocation4|}}} | country = {{{country4|}}} | deputy = {{{deputy4|}}} | deputyminister = {{{deputyminister4|}}} | headminister = {{{headminister4|}}} | district = {{{district4|}}} | firstminister = {{{firstminister4|}}} | governor-general = {{{governor-general4|}}} | governor_general = {{{governor_general4|}}} | governor = {{{governor4|}}} | jr/sr = {{{jr/sr4|}}} | jr/sr and state = {{{jr/sr and state4|}}} | leader = {{{leader4|}}} | legislature = {{{legislature4|}}} | lieutenant_governor = {{{lieutenant_governor4|}}} | lieutenant = {{{lieutenant4|}}} | minister_from = {{{minister_from4|}}} | minority_floor_leader = {{{minority_floor_leader4|}}} | majority_floor_leader = {{{majority_floor_leader4|}}} | majority_leader = {{#if: {{{majorityleader4|}}} | {{{majorityleader4}}} | {{{majority_leader4|}}} }} | majority = {{{majority4|}}} | minister = {{{minister4|}}} | minority_leader = {{#if: {{{minorityleader4|}}} | {{{minorityleader4}}} | {{{minority_leader4|}}} }} | monarch = {{{monarch4|}}} | nominator = {{{nominator4|}}} | office = {{{office4|}}} | order = {{{order4|}}} | parliament = {{{parliament4|}}} | parliamentarygroup = {{{parliamentarygroup4|}}} | predecessor = {{{predecessor4|}}} | preceding = {{{preceding4|}}} | preceded = {{{preceded4|}}} | premier = {{{premier4|}}} | president = {{{president4|}}} | primeminister = {{{primeminister4|}}} | riding = {{{riding4|}}} | state_assembly = {{{state_assembly4|}}} | state_delegate = {{{state_delegate4|}}} | state_house = {{{state_house4|}}} | state_legislature = {{{state_legislature4|}}} | state_senate = {{{state_senate4|}}} | state = {{{state4|}}} | status = {{{status4|}}} | subterm = {{{subterm4|}}} | suboffice = {{{suboffice4|}}} | succeeded = {{{succeeded4|}}} | succeeding = {{{succeeding4|}}} | successor = {{{successor4|}}} | taoiseach = {{{taoiseach4|}}} | termlabel = {{{term_label4|{{{termlabel4|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend4|}}}|{{{termend4}}}|{{{term_end4|}}}}} | termstart = {{#if:{{{termstart4|}}}|{{{termstart4}}}|{{{term_start4|}}}}} | term = {{{term4|}}} | title = {{{title4|}}} | vicegovernor = {{{vicegovernor4|}}} | vicepresident = {{{vicepresident4|}}} | vicepremier = {{{vicepremier4|}}} | viceprimeminister = {{{viceprimeminister4|}}} | party = {{{party|}}} | prior_term = {{{prior_term4|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname5|}}} | 1namedata = {{{1namedata5|}}} | 2blankname = {{{2blankname5|}}} | 2namedata = {{{2namedata5|}}} | 3blankname = {{{3blankname5|}}} | 3namedata = {{{3namedata5|}}} | 4blankname = {{{4blankname5|}}} | 4namedata = {{{4namedata5|}}} | 5blankname = {{{5blankname5|}}} | 5namedata = {{{5namedata5|}}} | alongside = {{{alongside5|}}} | ambassador_from = {{{ambassador_from5|}}} | appointer = {{#if: {{{appointer5|}}} | {{{appointer5}}} | {{{appointed5|}}} }} | assembly = {{{assembly5|}}} | assuming = {{{assuming5|}}} | chancellor = {{{chancellor5|}}} | co-leader = {{{co-leader5|}}} | constituency_{{#if:{{{constituency_AM5|}}}|AM|MP}} = {{#if: {{{constituency_AM5|}}} | {{{constituency_AM5}}} | {{{constituency_MP5|}}} }} | constituency = {{{constituency5|}}} | convocation = {{{convocation5|}}} | country = {{{country5|}}} | deputy = {{{deputy5|}}} | deputyminister = {{{deputyminister5|}}} | headminister = {{{headminister5|}}} | district = {{{district5|}}} | firstminister = {{{firstminister5|}}} | governor-general = {{{governor-general5|}}} | governor_general = {{{governor_general5|}}} | governor = {{{governor5|}}} | jr/sr = {{{jr/sr5|}}} | jr/sr and state = {{{jr/sr and state5|}}} | leader = {{{leader5|}}} | legislature = {{{legislature5|}}} | lieutenant_governor = {{{lieutenant_governor5|}}} | lieutenant = {{{lieutenant5|}}} | minister_from = {{{minister_from5|}}} | minority_floor_leader = {{{minority_floor_leader5|}}} | majority_floor_leader = {{{majority_floor_leader5|}}} | majority_leader = {{#if: {{{majorityleader5|}}} | {{{majorityleader5}}} | {{{majority_leader5|}}} }} | majority = {{{majority5|}}} | minister = {{{minister5|}}} | minority_leader = {{#if: {{{minorityleader5|}}} | {{{minorityleader5}}} | {{{minority_leader5|}}} }} | monarch = {{{monarch5|}}} | nominator = {{{nominator5|}}} | office = {{{office5|}}} | order = {{{order5|}}} | parliament = {{{parliament5|}}} | parliamentarygroup = {{{parliamentarygroup5|}}} | predecessor = {{{predecessor5|}}} | preceding = {{{preceding5|}}} | preceded = {{{preceded5|}}} | premier = {{{premier5|}}} | president = {{{president5|}}} | primeminister = {{{primeminister5|}}} | riding = {{{riding5|}}} | state_assembly = {{{state_assembly5|}}} | state_delegate = {{{state_delegate5|}}} | state_house = {{{state_house5|}}} | state_legislature = {{{state_legislature5|}}} | state_senate = {{{state_senate5|}}} | state = {{{state5|}}} | status = {{{status5|}}} | subterm = {{{subterm5|}}} | suboffice = {{{suboffice5|}}} | succeeded = {{{succeeded5|}}} | succeeding = {{{succeeding5|}}} | successor = {{{successor5|}}} | taoiseach = {{{taoiseach5|}}} | termlabel = {{{term_label5|{{{termlabel5|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend5|}}}|{{{termend5}}}|{{{term_end5|}}}}} | termstart = {{#if:{{{termstart5|}}}|{{{termstart5}}}|{{{term_start5|}}}}} | term = {{{term5|}}} | title = {{{title5|}}} | vicegovernor = {{{vicegovernor5|}}} | vicepresident = {{{vicepresident5|}}} | vicepremier = {{{vicepremier5|}}} | viceprimeminister = {{{viceprimeminister5|}}} | party = {{{party|}}} | prior_term = {{{prior_term5|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname6|}}} | 1namedata = {{{1namedata6|}}} | 2blankname = {{{2blankname6|}}} | 2namedata = {{{2namedata6|}}} | 3blankname = {{{3blankname6|}}} | 3namedata = {{{3namedata6|}}} | 4blankname = {{{4blankname6|}}} | 4namedata = {{{4namedata6|}}} | 5blankname = {{{5blankname6|}}} | 5namedata = {{{5namedata6|}}} | alongside = {{{alongside6|}}} | ambassador_from = {{{ambassador_from6|}}} | appointer = {{#if: {{{appointer6|}}} | {{{appointer6}}} | {{{appointed6|}}} }} | assembly = {{{assembly6|}}} | assuming = {{{assuming6|}}} | chancellor = {{{chancellor6|}}} | co-leader = {{{co-leader6|}}} | constituency_{{#if:{{{constituency_AM6|}}}|AM|MP}} = {{#if: {{{constituency_AM6|}}} | {{{constituency_AM6}}} | {{{constituency_MP6|}}} }} | constituency = {{{constituency6|}}} | convocation = {{{convocation6|}}} | country = {{{country6|}}} | deputy = {{{deputy6|}}} | deputyminister = {{{deputyminister6|}}} | headminister = {{{headminister6|}}} | district = {{{district6|}}} | firstminister = {{{firstminister6|}}} | governor-general = {{{governor-general6|}}} | governor_general = {{{governor_general6|}}} | governor = {{{governor6|}}} | jr/sr = {{{jr/sr6|}}} | jr/sr and state = {{{jr/sr and state6|}}} | leader = {{{leader6|}}} | legislature = {{{legislature6|}}} | lieutenant_governor = {{{lieutenant_governor6|}}} | lieutenant = {{{lieutenant6|}}} | minority_floor_leader = {{{minority_floor_leader6|}}} | minister_from = {{{minister_from6|}}} | majority_floor_leader = {{{majority_floor_leader6|}}} | majority_leader = {{#if: {{{majorityleader6|}}} | {{{majorityleader6}}} | {{{majority_leader6|}}} }} | majority = {{{majority6|}}} | minister = {{{minister6|}}} | minority_leader = {{#if: {{{minorityleader6|}}} | {{{minorityleader6}}} | {{{minority_leader6|}}} }} | monarch = {{{monarch6|}}} | nominator = {{{nominator6|}}} | office = {{{office6|}}} | order = {{{order6|}}} | parliament = {{{parliament6|}}} | parliamentarygroup = {{{parliamentarygroup6|}}} | predecessor = {{{predecessor6|}}} | preceding = {{{preceding6|}}} | preceded = {{{preceded6|}}} | premier = {{{premier6|}}} | president = {{{president6|}}} | primeminister = {{{primeminister6|}}} | riding = {{{riding6|}}} | state_assembly = {{{state_assembly6|}}} | state_delegate = {{{state_delegate6|}}} | state_house = {{{state_house6|}}} | state_legislature = {{{state_legislature6|}}} | state_senate = {{{state_senate6|}}} | state = {{{state6|}}} | status = {{{status6|}}} | subterm = {{{subterm6|}}} | suboffice = {{{suboffice6|}}} | succeeded = {{{succeeded6|}}} | succeeding = {{{succeeding6|}}} | successor = {{{successor6|}}} | taoiseach = {{{taoiseach6|}}} | termlabel = {{{term_label6|{{{termlabel6|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend6|}}}|{{{termend6}}}|{{{term_end6|}}}}} | termstart = {{#if:{{{termstart6|}}}|{{{termstart6}}}|{{{term_start6|}}}}} | term = {{{term6|}}} | title = {{{title6|}}} | vicegovernor = {{{vicegovernor6|}}} | vicepresident = {{{vicepresident6|}}} | vicepremier = {{{vicepremier6|}}} | viceprimeminister = {{{viceprimeminister6|}}} | party = {{{party|}}} | prior_term = {{{prior_term6|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname7|}}} | 1namedata = {{{1namedata7|}}} | 2blankname = {{{2blankname7|}}} | 2namedata = {{{2namedata7|}}} | 3blankname = {{{3blankname7|}}} | 3namedata = {{{3namedata7|}}} | 4blankname = {{{4blankname7|}}} | 4namedata = {{{4namedata7|}}} | 5blankname = {{{5blankname7|}}} | 5namedata = {{{5namedata7|}}} | alongside = {{{alongside7|}}} | ambassador_from = {{{ambassador_from7|}}} | appointer = {{#if: {{{appointer7|}}} | {{{appointer7}}} | {{{appointed7|}}} }} | assembly = {{{assembly7|}}} | assuming = {{{assuming7|}}} | chancellor = {{{chancellor7|}}} | co-leader = {{{co-leader7|}}} | constituency_{{#if:{{{constituency_AM7|}}}|AM|MP}} = {{#if: {{{constituency_AM7|}}} | {{{constituency_AM7}}} | {{{constituency_MP7|}}} }} | constituency = {{{constituency7|}}} | convocation = {{{convocation7|}}} | country = {{{country7|}}} | deputy = {{{deputy7|}}} | deputyminister = {{{deputyminister7|}}} | headminister = {{{headminister7|}}} | district = {{{district7|}}} | firstminister = {{{firstminister7|}}} | governor-general = {{{governor-general7|}}} | governor_general = {{{governor_general7|}}} | governor = {{{governor7|}}} | jr/sr = {{{jr/sr7|}}} | jr/sr and state = {{{jr/sr and state7|}}} | leader = {{{leader7|}}} | legislature = {{{legislature7|}}} | lieutenant_governor = {{{lieutenant_governor7|}}} | lieutenant = {{{lieutenant7|}}} | minister_from = {{{minister_from7|}}} | minority_floor_leader = {{{minority_floor_leader7|}}} | majority_floor_leader = {{{majority_floor_leader7|}}} | majority_leader = {{#if: {{{majorityleader7|}}} | {{{majorityleader7}}} | {{{majority_leader7|}}} }} | majority = {{{majority7|}}} | minister = {{{minister7|}}} | minority_leader = {{#if: {{{minorityleader7|}}} | {{{minorityleader7}}} | {{{minority_leader7|}}} }} | monarch = {{{monarch7|}}} | nominator = {{{nominator7|}}} | office = {{{office7|}}} | order = {{{order7|}}} | parliament = {{{parliament7|}}} | parliamentarygroup = {{{parliamentarygroup7|}}} | predecessor = {{{predecessor7|}}} | preceding = {{{preceding7|}}} | preceded = {{{preceded7|}}} | premier = {{{premier7|}}} | president = {{{president7|}}} | primeminister = {{{primeminister7|}}} | riding = {{{riding7|}}} | state_assembly = {{{state_assembly7|}}} | state_delegate = {{{state_delegate7|}}} | state_house = {{{state_house7|}}} | state_legislature = {{{state_legislature7|}}} | state_senate = {{{state_senate7|}}} | state = {{{state7|}}} | status = {{{status7|}}} | subterm = {{{subterm7|}}} | suboffice = {{{suboffice7|}}} | succeeded = {{{succeeded7|}}} | succeeding = {{{succeeding7|}}} | successor = {{{successor7|}}} | taoiseach = {{{taoiseach7|}}} | termlabel = {{{term_label7|{{{termlabel7|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend7|}}}|{{{termend7}}}|{{{term_end7|}}}}} | termstart = {{#if:{{{termstart7|}}}|{{{termstart7}}}|{{{term_start7|}}}}} | term = {{{term7|}}} | title = {{{title7|}}} | vicegovernor = {{{vicegovernor7|}}} | vicepresident = {{{vicepresident7|}}} | vicepremier = {{{vicepremier7|}}} | viceprimeminister = {{{viceprimeminister7|}}} | party = {{{party|}}} | prior_term = {{{prior_term7|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname8|}}} | 1namedata = {{{1namedata8|}}} | 2blankname = {{{2blankname8|}}} | 2namedata = {{{2namedata8|}}} | 3blankname = {{{3blankname8|}}} | 3namedata = {{{3namedata8|}}} | 4blankname = {{{4blankname8|}}} | 4namedata = {{{4namedata8|}}} | 5blankname = {{{5blankname8|}}} | 5namedata = {{{5namedata8|}}} | alongside = {{{alongside8|}}} | ambassador_from = {{{ambassador_from8|}}} | appointer = {{#if: {{{appointer8|}}} | {{{appointer8}}} | {{{appointed8|}}} }} | assembly = {{{assembly8|}}} | assuming = {{{assuming8|}}} | chancellor = {{{chancellor8|}}} | co-leader = {{{co-leader8|}}} | constituency_{{#if:{{{constituency_AM8|}}}|AM|MP}} = {{#if: {{{constituency_AM8|}}} | {{{constituency_AM8}}} | {{{constituency_MP8|}}} }} | constituency = {{{constituency8|}}} | convocation = {{{convocation8|}}} | country = {{{country8|}}} | deputy = {{{deputy8|}}} | deputyminister = {{{deputyminister8|}}} | headminister = {{{headminister8|}}} | district = {{{district8|}}} | firstminister = {{{firstminister8|}}} | governor-general = {{{governor-general8|}}} | governor_general = {{{governor_general8|}}} | governor = {{{governor8|}}} | jr/sr = {{{jr/sr8|}}} | jr/sr and state = {{{jr/sr and state8|}}} | leader = {{{leader8|}}} | legislature = {{{legislature8|}}} | lieutenant_governor = {{{lieutenant_governor8|}}} | lieutenant = {{{lieutenant8|}}} | minister_from = {{{minister_from8|}}} | minority_floor_leader = {{{minority_floor_leader8|}}} | majority_floor_leader = {{{majority_floor_leader8|}}} | majority_leader = {{#if: {{{majorityleader8|}}} | {{{majorityleader8}}} | {{{majority_leader8|}}} }} | majority = {{{majority8|}}} | minister = {{{minister8|}}} | minority_leader = {{#if: {{{minorityleader8|}}} | {{{minorityleader8}}} | {{{minority_leader8|}}} }} | monarch = {{{monarch8|}}} | nominator = {{{nominator8|}}} | office = {{{office8|}}} | order = {{{order8|}}} | parliament = {{{parliament8|}}} | parliamentarygroup = {{{parliamentarygroup8|}}} | predecessor = {{{predecessor8|}}} | preceding = {{{preceding8|}}} | preceded = {{{preceded8|}}} | premier = {{{premier8|}}} | president = {{{president8|}}} | primeminister = {{{primeminister8|}}} | riding = {{{riding8|}}} | state_assembly = {{{state_assembly8|}}} | state_delegate = {{{state_delegate8|}}} | state_house = {{{state_house8|}}} | state_legislature = {{{state_legislature8|}}} | state_senate = {{{state_senate8|}}} | state = {{{state8|}}} | status = {{{status8|}}} | subterm = {{{subterm8|}}} | suboffice = {{{suboffice8|}}} | succeeded = {{{succeeded8|}}} | succeeding = {{{succeeding8|}}} | successor = {{{successor8|}}} | taoiseach = {{{taoiseach8|}}} | termlabel = {{{term_label8|{{{termlabel8|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend8|}}}|{{{termend8}}}|{{{term_end8|}}}}} | termstart = {{#if:{{{termstart8|}}}|{{{termstart8}}}|{{{term_start8|}}}}} | term = {{{term8|}}} | title = {{{title8|}}} | vicegovernor = {{{vicegovernor8|}}} | vicepresident = {{{vicepresident8|}}} | vicepremier = {{{vicepremier8|}}} | viceprimeminister = {{{viceprimeminister8|}}} | party = {{{party|}}} | prior_term = {{{prior_term8|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname9|}}} | 1namedata = {{{1namedata9|}}} | 2blankname = {{{2blankname9|}}} | 2namedata = {{{2namedata9|}}} | 3blankname = {{{3blankname9|}}} | 3namedata = {{{3namedata9|}}} | 4blankname = {{{4blankname9|}}} | 4namedata = {{{4namedata9|}}} | 5blankname = {{{5blankname9|}}} | 5namedata = {{{5namedata9|}}} | alongside = {{{alongside9|}}} | ambassador_from = {{{ambassador_from9|}}} | appointer = {{#if: {{{appointer9|}}} | {{{appointer9}}} | {{{appointed9|}}} }} | assembly = {{{assembly9|}}} | assuming = {{{assuming9|}}} | chancellor = {{{chancellor9|}}} | co-leader = {{{co-leader9|}}} | constituency_{{#if:{{{constituency_AM9|}}}|AM|MP}} = {{#if: {{{constituency_AM9|}}} | {{{constituency_AM9}}} | {{{constituency_MP9|}}} }} | constituency = {{{constituency9|}}} | convocation = {{{convocation9|}}} | country = {{{country9|}}} | deputy = {{{deputy9|}}} | deputyminister = {{{deputyminister9|}}} | headminister = {{{headminister9|}}} | district = {{{district9|}}} | firstminister = {{{firstminister9|}}} | governor-general = {{{governor-general9|}}} | governor_general = {{{governor_general9|}}} | governor = {{{governor9|}}} | jr/sr = {{{jr/sr9|}}} | jr/sr and state = {{{jr/sr and state9|}}} | leader = {{{leader9|}}} | legislature = {{{legislature9|}}} | lieutenant_governor = {{{lieutenant_governor9|}}} | lieutenant = {{{lieutenant9|}}} | minister_from = {{{minister_from9|}}} | minority_floor_leader = {{{minority_floor_leader9|}}} | majority_floor_leader = {{{majority_floor_leader9|}}} | majority_leader = {{#if: {{{majorityleader9|}}} | {{{majorityleader9}}} | {{{majority_leader9|}}} }} | majority = {{{majority9|}}} | minister = {{{minister9|}}} | minority_leader = {{#if: {{{minorityleader9|}}} | {{{minorityleader9}}} | {{{minority_leader9|}}} }} | monarch = {{{monarch9|}}} | nominator = {{{nominator9|}}} | office = {{{office9|}}} | order = {{{order9|}}} | parliament = {{{parliament9|}}} | parliamentarygroup = {{{parliamentarygroup9|}}} | predecessor = {{{predecessor9|}}} | preceding = {{{preceding9|}}} | preceded = {{{preceded9|}}} | premier = {{{premier9|}}} | president = {{{president9|}}} | primeminister = {{{primeminister9|}}} | riding = {{{riding9|}}} | state_assembly = {{{state_assembly9|}}} | state_delegate = {{{state_delegate9|}}} | state_house = {{{state_house9|}}} | state_legislature = {{{state_legislature9|}}} | state_senate = {{{state_senate9|}}} | state = {{{state9|}}} | status = {{{status9|}}} | subterm = {{{subterm9|}}} | suboffice = {{{suboffice9|}}} | succeeded = {{{succeeded9|}}} | succeeding = {{{succeeding9|}}} | successor = {{{successor9|}}} | taoiseach = {{{taoiseach9|}}} | termlabel = {{{term_label9|{{{termlabel9|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend9|}}}|{{{termend9}}}|{{{term_end9|}}}}} | termstart = {{#if:{{{termstart9|}}}|{{{termstart9}}}|{{{term_start9|}}}}} | term = {{{term9|}}} | title = {{{title9|}}} | vicegovernor = {{{vicegovernor9|}}} | vicepresident = {{{vicepresident9|}}} | vicepremier = {{{vicepremier9|}}} | viceprimeminister = {{{viceprimeminister9|}}} | party = {{{party|}}} | prior_term = {{{prior_term9|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname10|}}} | 1namedata = {{{1namedata10|}}} | 2blankname = {{{2blankname10|}}} | 2namedata = {{{2namedata10|}}} | 3blankname = {{{3blankname10|}}} | 3namedata = {{{3namedata10|}}} | 4blankname = {{{4blankname10|}}} | 4namedata = {{{4namedata10|}}} | 5blankname = {{{5blankname10|}}} | 5namedata = {{{5namedata10|}}} | alongside = {{{alongside10|}}} | ambassador_from = {{{ambassador_from10|}}} | appointer = {{#if: {{{appointer10|}}} | {{{appointer10}}} | {{{appointed10|}}} }} | assembly = {{{assembly10|}}} | assuming = {{{assuming10|}}} | chancellor = {{{chancellor10|}}} | co-leader = {{{co-leader10|}}} | constituency_{{#if:{{{constituency_AM10|}}}|AM|MP}} = {{#if: {{{constituency_AM10|}}} | {{{constituency_AM10}}} | {{{constituency_MP10|}}} }} | constituency = {{{constituency10|}}} | convocation = {{{convocation10|}}} | country = {{{country10|}}} | deputy = {{{deputy10|}}} | deputyminister = {{{deputyminister10|}}} | headminister = {{{headminister10|}}} | district = {{{district10|}}} | firstminister = {{{firstminister10|}}} | governor-general = {{{governor-general10|}}} | governor_general = {{{governor_general10|}}} | governor = {{{governor10|}}} | jr/sr = {{{jr/sr10|}}} | jr/sr and state = {{{jr/sr and state10|}}} | leader = {{{leader10|}}} | legislature = {{{legislature10|}}} | lieutenant_governor = {{{lieutenant_governor10|}}} | lieutenant = {{{lieutenant10|}}} | minister_from = {{{minister_from10|}}} | minority_floor_leader = {{{minority_floor_leader10|}}} | majority_floor_leader = {{{majority_floor_leader10|}}} | majority_leader = {{#if: {{{majorityleader10|}}} | {{{majorityleader10}}} | {{{majority_leader10|}}} }} | majority = {{{majority10|}}} | minister = {{{minister10|}}} | minority_leader = {{#if: {{{minorityleader10|}}} | {{{minorityleader10}}} | {{{minority_leader10|}}} }} | monarch = {{{monarch10|}}} | nominator = {{{nominator10|}}} | office = {{{office10|}}} | order = {{{order10|}}} | parliament = {{{parliament10|}}} | parliamentarygroup = {{{parliamentarygroup10|}}} | predecessor = {{{predecessor10|}}} | preceding = {{{preceding10|}}} | preceded = {{{preceded10|}}} | premier = {{{premier10|}}} | president = {{{president10|}}} | primeminister = {{{primeminister10|}}} | riding = {{{riding10|}}} | state_assembly = {{{state_assembly10|}}} | state_delegate = {{{state_delegate10|}}} | state_house = {{{state_house10|}}} | state_legislature = {{{state_legislature10|}}} | state_senate = {{{state_senate10|}}} | state = {{{state10|}}} | status = {{{status10|}}} | subterm = {{{subterm10|}}} | suboffice = {{{suboffice10|}}} | succeeded = {{{succeeded10|}}} | succeeding = {{{succeeding10|}}} | successor = {{{successor10|}}} | taoiseach = {{{taoiseach10|}}} | termlabel = {{{term_label10|{{{termlabel10|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend10|}}}|{{{termend10}}}|{{{term_end10|}}}}} | termstart = {{#if:{{{termstart10|}}}|{{{termstart10}}}|{{{term_start10|}}}}} | term = {{{term10|}}} | title = {{{title10|}}} | vicegovernor = {{{vicegovernor10|}}} | vicepresident = {{{vicepresident10|}}} | vicepremier = {{{vicepremier10|}}} | viceprimeminister = {{{viceprimeminister10|}}} | party = {{{party|}}} | prior_term = {{{prior_term10|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname11|}}} | 1namedata = {{{1namedata11|}}} | 2blankname = {{{2blankname11|}}} | 2namedata = {{{2namedata11|}}} | 3blankname = {{{3blankname11|}}} | 3namedata = {{{3namedata11|}}} | 4blankname = {{{4blankname11|}}} | 4namedata = {{{4namedata11|}}} | 5blankname = {{{5blankname11|}}} | 5namedata = {{{5namedata11|}}} | alongside = {{{alongside11|}}} | ambassador_from = {{{ambassador_from11|}}} | appointer = {{#if: {{{appointer11|}}} | {{{appointer11}}} | {{{appointed11|}}} }} | assembly = {{{assembly11|}}} | assuming = {{{assuming11|}}} | chancellor = {{{chancellor11|}}} | co-leader = {{{co-leader11|}}} | constituency_{{#if:{{{constituency_AM11|}}}|AM|MP}} = {{#if: {{{constituency_AM11|}}} | {{{constituency_AM11}}} | {{{constituency_MP11|}}} }} | constituency = {{{constituency11|}}} | convocation = {{{convocation11|}}} | country = {{{country11|}}} | deputy = {{{deputy11|}}} | deputyminister = {{{deputyminister11|}}} | headminister = {{{headminister11|}}} | district = {{{district11|}}} | firstminister = {{{firstminister11|}}} | governor-general = {{{governor-general11|}}} | governor_general = {{{governor_general11|}}} | governor = {{{governor11|}}} | jr/sr = {{{jr/sr11|}}} | jr/sr and state = {{{jr/sr and state11|}}} | leader = {{{leader11|}}} | legislature = {{{legislature11|}}} | lieutenant_governor = {{{lieutenant_governor11|}}} | lieutenant = {{{lieutenant11|}}} | minister_from = {{{minister_from11|}}} | minority_floor_leader = {{{minority_floor_leader11|}}} | majority_floor_leader = {{{majority_floor_leader11|}}} | majority_leader = {{#if: {{{majorityleader11|}}} | {{{majorityleader11}}} | {{{majority_leader11|}}} }} | majority = {{{majority11|}}} | minister = {{{minister11|}}} | minority_leader = {{#if: {{{minorityleader11|}}} | {{{minorityleader11}}} | {{{minority_leader11|}}} }} | monarch = {{{monarch11|}}} | nominator = {{{nominator11|}}} | office = {{{office11|}}} | order = {{{order11|}}} | parliament = {{{parliament11|}}} | parliamentarygroup = {{{parliamentarygroup11|}}} | predecessor = {{{predecessor11|}}} | preceding = {{{preceding11|}}} | preceded = {{{preceded11|}}} | premier = {{{premier11|}}} | president = {{{president11|}}} | primeminister = {{{primeminister11|}}} | riding = {{{riding11|}}} | state_assembly = {{{state_assembly11|}}} | state_delegate = {{{state_delegate11|}}} | state_house = {{{state_house11|}}} | state_legislature = {{{state_legislature11|}}} | state_senate = {{{state_senate11|}}} | state = {{{state11|}}} | status = {{{status11|}}} | subterm = {{{subterm11|}}} | suboffice = {{{suboffice11|}}} | succeeded = {{{succeeded11|}}} | succeeding = {{{succeeding11|}}} | successor = {{{successor11|}}} | taoiseach = {{{taoiseach11|}}} | termlabel = {{{term_label11|{{{termlabel11|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend11|}}}|{{{termend11}}}|{{{term_end11|}}}}} | termstart = {{#if:{{{termstart11|}}}|{{{termstart11}}}|{{{term_start11|}}}}} | term = {{{term11|}}} | title = {{{title11|}}} | vicegovernor = {{{vicegovernor11|}}} | vicepresident = {{{vicepresident11|}}} | vicepremier = {{{vicepremier11|}}} | viceprimeminister = {{{viceprimeminister11|}}} | party = {{{party|}}} | prior_term = {{{prior_term11|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname12|}}} | 1namedata = {{{1namedata12|}}} | 2blankname = {{{2blankname12|}}} | 2namedata = {{{2namedata12|}}} | 3blankname = {{{3blankname12|}}} | 3namedata = {{{3namedata12|}}} | 4blankname = {{{4blankname12|}}} | 4namedata = {{{4namedata12|}}} | 5blankname = {{{5blankname12|}}} | 5namedata = {{{5namedata12|}}} | alongside = {{{alongside12|}}} | ambassador_from = {{{ambassador_from12|}}} | appointer = {{#if: {{{appointer12|}}} | {{{appointer12}}} | {{{appointed12|}}} }} | assembly = {{{assembly12|}}} | assuming = {{{assuming12|}}} | chancellor = {{{chancellor12|}}} | co-leader = {{{co-leader12|}}} | constituency_{{#if:{{{constituency_AM12|}}}|AM|MP}} = {{#if: {{{constituency_AM12|}}} | {{{constituency_AM12}}} | {{{constituency_MP12|}}} }} | constituency = {{{constituency12|}}} | convocation = {{{convocation12|}}} | country = {{{country12|}}} | deputy = {{{deputy12|}}} | deputyminister = {{{deputyminister12|}}} | headminister = {{{headminister12|}}} | district = {{{district12|}}} | firstminister = {{{firstminister12|}}} | governor-general = {{{governor-general12|}}} | governor_general = {{{governor_general12|}}} | governor = {{{governor12|}}} | jr/sr = {{{jr/sr12|}}} | jr/sr and state = {{{jr/sr and state12|}}} | leader = {{{leader12|}}} | legislature = {{{legislature12|}}} | lieutenant_governor = {{{lieutenant_governor12|}}} | lieutenant = {{{lieutenant12|}}} | minister_from = {{{minister_from12|}}} | minority_floor_leader = {{{minority_floor_leader12|}}} | majority_floor_leader = {{{majority_floor_leader12|}}} | majority_leader = {{#if: {{{majorityleader12|}}} | {{{majorityleader12}}} | {{{majority_leader12|}}} }} | majority = {{{majority12|}}} | minister = {{{minister12|}}} | minority_leader = {{#if: {{{minorityleader12|}}} | {{{minorityleader12}}} | {{{minority_leader12|}}} }} | monarch = {{{monarch12|}}} | nominator = {{{nominator12|}}} | office = {{{office12|}}} | order = {{{order12|}}} | parliament = {{{parliament12|}}} | parliamentarygroup = {{{parliamentarygroup12|}}} | predecessor = {{{predecessor12|}}} | preceding = {{{preceding12|}}} | preceded = {{{preceded12|}}} | premier = {{{premier12|}}} | president = {{{president12|}}} | primeminister = {{{primeminister12|}}} | riding = {{{riding12|}}} | state_assembly = {{{state_assembly12|}}} | state_delegate = {{{state_delegate12|}}} | state_house = {{{state_house12|}}} | state_legislature = {{{state_legislature12|}}} | state_senate = {{{state_senate12|}}} | state = {{{state12|}}} | status = {{{status12|}}} | subterm = {{{subterm12|}}} | suboffice = {{{suboffice12|}}} | succeeded = {{{succeeded12|}}} | succeeding = {{{succeeding12|}}} | successor = {{{successor12|}}} | taoiseach = {{{taoiseach12|}}} | termlabel = {{{term_label12|{{{termlabel12|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend12|}}}|{{{termend12}}}|{{{term_end12|}}}}} | termstart = {{#if:{{{termstart12|}}}|{{{termstart12}}}|{{{term_start12|}}}}} | term = {{{term12|}}} | title = {{{title12|}}} | vicegovernor = {{{vicegovernor12|}}} | vicepresident = {{{vicepresident12|}}} | vicepremier = {{{vicepremier12|}}} | viceprimeminister = {{{viceprimeminister12|}}} | party = {{{party|}}} | prior_term = {{{prior_term12|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname13|}}} | 1namedata = {{{1namedata13|}}} | 2blankname = {{{2blankname13|}}} | 2namedata = {{{2namedata13|}}} | 3blankname = {{{3blankname13|}}} | 3namedata = {{{3namedata13|}}} | 4blankname = {{{4blankname13|}}} | 4namedata = {{{4namedata13|}}} | 5blankname = {{{5blankname13|}}} | 5namedata = {{{5namedata13|}}} | alongside = {{{alongside13|}}} | ambassador_from = {{{ambassador_from13|}}} | appointer = {{#if: {{{appointer13|}}} | {{{appointer13}}} | {{{appointed13|}}} }} | assembly = {{{assembly13|}}} | assuming = {{{assuming13|}}} | chancellor = {{{chancellor13|}}} | co-leader = {{{co-leader13|}}} | constituency_{{#if:{{{constituency_AM13|}}}|AM|MP}} = {{#if: {{{constituency_AM13|}}} | {{{constituency_AM13}}} | {{{constituency_MP13|}}} }} | constituency = {{{constituency13|}}} | convocation = {{{convocation13|}}} | country = {{{country13|}}} | deputy = {{{deputy13|}}} | deputyminister = {{{deputyminister13|}}} | headminister = {{{headminister13|}}} | district = {{{district13|}}} | firstminister = {{{firstminister13|}}} | governor-general = {{{governor-general13|}}} | governor_general = {{{governor_general13|}}} | governor = {{{governor13|}}} | jr/sr = {{{jr/sr13|}}} | jr/sr and state = {{{jr/sr and state13|}}} | leader = {{{leader13|}}} | legislature = {{{legislature13|}}} | lieutenant_governor = {{{lieutenant_governor13|}}} | lieutenant = {{{lieutenant13|}}} | minister_from = {{{minister_from13|}}} | minority_floor_leader = {{{minority_floor_leader13|}}} | majority_floor_leader = {{{majority_floor_leader13|}}} | majority_leader = {{#if: {{{majorityleader13|}}} | {{{majorityleader13}}} | {{{majority_leader13|}}} }} | majority = {{{majority13|}}} | minister = {{{minister13|}}} | minority_leader = {{#if: {{{minorityleader13|}}} | {{{minorityleader13}}} | {{{minority_leader13|}}} }} | monarch = {{{monarch13|}}} | nominator = {{{nominator13|}}} | office = {{{office13|}}} | order = {{{order13|}}} | parliament = {{{parliament13|}}} | parliamentarygroup = {{{parliamentarygroup13|}}} | predecessor = {{{predecessor13|}}} | preceding = {{{preceding13|}}} | preceded = {{{preceded13|}}} | premier = {{{premier13|}}} | president = {{{president13|}}} | primeminister = {{{primeminister13|}}} | riding = {{{riding13|}}} | state_assembly = {{{state_assembly13|}}} | state_delegate = {{{state_delegate13|}}} | state_house = {{{state_house13|}}} | state_legislature = {{{state_legislature13|}}} | state_senate = {{{state_senate13|}}} | state = {{{state13|}}} | status = {{{status13|}}} | subterm = {{{subterm13|}}} | suboffice = {{{suboffice13|}}} | succeeded = {{{succeeded13|}}} | succeeding = {{{succeeding13|}}} | successor = {{{successor13|}}} | taoiseach = {{{taoiseach13|}}} | termlabel = {{{term_label13|{{{termlabel13|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend13|}}}|{{{termend13}}}|{{{term_end13|}}}}} | termstart = {{#if:{{{termstart13|}}}|{{{termstart13}}}|{{{term_start13|}}}}} | term = {{{term13|}}} | title = {{{title13|}}} | vicegovernor = {{{vicegovernor13|}}} | vicepresident = {{{vicepresident13|}}} | vicepremier = {{{vicepremier13|}}} | viceprimeminister = {{{viceprimeminister13|}}} | party = {{{party|}}} | prior_term = {{{prior_term13|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname14|}}} | 1namedata = {{{1namedata14|}}} | 2blankname = {{{2blankname14|}}} | 2namedata = {{{2namedata14|}}} | 3blankname = {{{3blankname14|}}} | 3namedata = {{{3namedata14|}}} | 4blankname = {{{4blankname14|}}} | 4namedata = {{{4namedata14|}}} | 5blankname = {{{5blankname14|}}} | 5namedata = {{{5namedata14|}}} | alongside = {{{alongside14|}}} | ambassador_from = {{{ambassador_from14|}}} | appointer = {{#if: {{{appointer14|}}} | {{{appointer14}}} | {{{appointed14|}}} }} | assembly = {{{assembly14|}}} | assuming = {{{assuming14|}}} | chancellor = {{{chancellor14|}}} | co-leader = {{{co-leader14|}}} | constituency_{{#if:{{{constituency_AM14|}}}|AM|MP}} = {{#if: {{{constituency_AM14|}}} | {{{constituency_AM14}}} | {{{constituency_MP14|}}} }} | constituency = {{{constituency14|}}} | convocation = {{{convocation14|}}} | country = {{{country14|}}} | deputy = {{{deputy14|}}} | deputyminister = {{{deputyminister14|}}} | headminister = {{{headminister14|}}} | district = {{{district14|}}} | firstminister = {{{firstminister14|}}} | governor-general = {{{governor-general14|}}} | governor_general = {{{governor_general14|}}} | governor = {{{governor14|}}} | jr/sr = {{{jr/sr14|}}} | jr/sr and state = {{{jr/sr and state14|}}} | leader = {{{leader14|}}} | legislature = {{{legislature14|}}} | lieutenant_governor = {{{lieutenant_governor14|}}} | lieutenant = {{{lieutenant14|}}} | minister_from = {{{minister_from14|}}} | minority_floor_leader = {{{minority_floor_leader14|}}} | majority_floor_leader = {{{majority_floor_leader14|}}} | majority_leader = {{#if: {{{majorityleader14|}}} | {{{majorityleader14}}} | {{{majority_leader14|}}} }} | majority = {{{majority14|}}} | minister = {{{minister14|}}} | minority_leader = {{#if: {{{minorityleader14|}}} | {{{minorityleader14}}} | {{{minority_leader14|}}} }} | monarch = {{{monarch14|}}} | nominator = {{{nominator14|}}} | office = {{{office14|}}} | order = {{{order14|}}} | parliament = {{{parliament14|}}} | parliamentarygroup = {{{parliamentarygroup14|}}} | predecessor = {{{predecessor14|}}} | preceding = {{{preceding14|}}} | preceded = {{{preceded14|}}} | premier = {{{premier14|}}} | president = {{{president14|}}} | primeminister = {{{primeminister14|}}} | riding = {{{riding14|}}} | state_assembly = {{{state_assembly14|}}} | state_delegate = {{{state_delegate14|}}} | state_house = {{{state_house14|}}} | state_legislature = {{{state_legislature14|}}} | state_senate = {{{state_senate14|}}} | state = {{{state14|}}} | status = {{{status14|}}} | subterm = {{{subterm14|}}} | suboffice = {{{suboffice14|}}} | succeeded = {{{succeeded14|}}} | succeeding = {{{succeeding14|}}} | successor = {{{successor14|}}} | taoiseach = {{{taoiseach14|}}} | termlabel = {{{term_label14|{{{termlabel14|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend14|}}}|{{{termend14}}}|{{{term_end14|}}}}} | termstart = {{#if:{{{termstart14|}}}|{{{termstart14}}}|{{{term_start14|}}}}} | term = {{{term14|}}} | title = {{{title14|}}} | vicegovernor = {{{vicegovernor14|}}} | vicepresident = {{{vicepresident14|}}} | vicepremier = {{{vicepremier14|}}} | viceprimeminister = {{{viceprimeminister14|}}} | party = {{{party|}}} | prior_term = {{{prior_term14|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname15|}}} | 1namedata = {{{1namedata15|}}} | 2blankname = {{{2blankname15|}}} | 2namedata = {{{2namedata15|}}} | 3blankname = {{{3blankname15|}}} | 3namedata = {{{3namedata15|}}} | 4blankname = {{{4blankname15|}}} | 4namedata = {{{4namedata15|}}} | 5blankname = {{{5blankname15|}}} | 5namedata = {{{5namedata15|}}} | alongside = {{{alongside15|}}} | ambassador_from = {{{ambassador_from15|}}} | appointer = {{#if: {{{appointer15|}}} | {{{appointer15}}} | {{{appointed15|}}} }} | assembly = {{{assembly15|}}} | assuming = {{{assuming15|}}} | chancellor = {{{chancellor15|}}} | co-leader = {{{co-leader15|}}} | constituency_{{#if:{{{constituency_AM15|}}}|AM|MP}} = {{#if: {{{constituency_AM15|}}} | {{{constituency_AM15}}} | {{{constituency_MP15|}}} }} | constituency = {{{constituency15|}}} | convocation = {{{convocation15|}}} | country = {{{country15|}}} | deputy = {{{deputy15|}}} | deputyminister = {{{deputyminister15|}}} | headminister = {{{headminister15|}}} | district = {{{district15|}}} | firstminister = {{{firstminister15|}}} | governor-general = {{{governor-general15|}}} | governor_general = {{{governor_general15|}}} | governor = {{{governor15|}}} | jr/sr = {{{jr/sr15|}}} | jr/sr and state = {{{jr/sr and state15|}}} | leader = {{{leader15|}}} | legislature = {{{legislature15|}}} | lieutenant_governor = {{{lieutenant_governor15|}}} | lieutenant = {{{lieutenant15|}}} | minister_from = {{{minister_from15|}}} | minority_floor_leader = {{{minority_floor_leader15|}}} | majority_floor_leader = {{{majority_floor_leader15|}}} | majority_leader = {{#if: {{{majorityleader15|}}} | {{{majorityleader15}}} | {{{majority_leader15|}}} }} | majority = {{{majority15|}}} | minister = {{{minister15|}}} | minority_leader = {{#if: {{{minorityleader15|}}} | {{{minorityleader15}}} | {{{minority_leader15|}}} }} | monarch = {{{monarch15|}}} | nominator = {{{nominator15|}}} | office = {{{office15|}}} | order = {{{order15|}}} | parliament = {{{parliament15|}}} | parliamentarygroup = {{{parliamentarygroup15|}}} | predecessor = {{{predecessor15|}}} | preceding = {{{preceding15|}}} | preceded = {{{preceded15|}}} | premier = {{{premier15|}}} | president = {{{president15|}}} | primeminister = {{{primeminister15|}}} | riding = {{{riding15|}}} | state_assembly = {{{state_assembly15|}}} | state_delegate = {{{state_delegate15|}}} | state_house = {{{state_house15|}}} | state_legislature = {{{state_legislature15|}}} | state_senate = {{{state_senate15|}}} | state = {{{state15|}}} | status = {{{status15|}}} | subterm = {{{subterm15|}}} | suboffice = {{{suboffice15|}}} | succeeded = {{{succeeded15|}}} | succeeding = {{{succeeding15|}}} | successor = {{{successor15|}}} | taoiseach = {{{taoiseach15|}}} | termlabel = {{{term_label15|{{{termlabel15|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend15|}}}|{{{termend15}}}|{{{term_end15|}}}}} | termstart = {{#if:{{{termstart15|}}}|{{{termstart15}}}|{{{term_start15|}}}}} | term = {{{term15|}}} | title = {{{title15|}}} | vicegovernor = {{{vicegovernor15|}}} | vicepresident = {{{vicepresident15|}}} | vicepremier = {{{vicepremier15|}}} | viceprimeminister = {{{viceprimeminister15|}}} | party = {{{party|}}} | prior_term = {{{prior_term15|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname16|}}} | 1namedata = {{{1namedata16|}}} | 2blankname = {{{2blankname16|}}} | 2namedata = {{{2namedata16|}}} | 3blankname = {{{3blankname16|}}} | 3namedata = {{{3namedata16|}}} | 4blankname = {{{4blankname16|}}} | 4namedata = {{{4namedata16|}}} | 5blankname = {{{5blankname16|}}} | 5namedata = {{{5namedata16|}}} | alongside = {{{alongside16|}}} | ambassador_from = {{{ambassador_from16|}}} | appointer = {{#if: {{{appointer16|}}} | {{{appointer16}}} | {{{appointed16|}}} }} | assembly = {{{assembly16|}}} | assuming = {{{assuming16|}}} | chancellor = {{{chancellor16|}}} | co-leader = {{{co-leader16|}}} | constituency_{{#if:{{{constituency_AM16|}}}|AM|MP}} = {{#if: {{{constituency_AM16|}}} | {{{constituency_AM16}}} | {{{constituency_MP16|}}} }} | constituency = {{{constituency16|}}} | convocation = {{{convocation16|}}} | country = {{{country16|}}} | deputy = {{{deputy16|}}} | deputyminister = {{{deputyminister16|}}} | headminister = {{{headminister16|}}} | district = {{{district16|}}} | firstminister = {{{firstminister16|}}} | governor-general = {{{governor-general16|}}} | governor_general = {{{governor_general16|}}} | governor = {{{governor16|}}} | jr/sr = {{{jr/sr16|}}} | jr/sr and state = {{{jr/sr and state16|}}} | leader = {{{leader16|}}} | legislature = {{{legislature16|}}} | lieutenant_governor = {{{lieutenant_governor16|}}} | lieutenant = {{{lieutenant16|}}} | minister_from = {{{minister_from16|}}} | minority_floor_leader = {{{minority_floor_leader16|}}} | majority_floor_leader = {{{majority_floor_leader16|}}} | majority_leader = {{#if: {{{majorityleader16|}}} | {{{majorityleader16}}} | {{{majority_leader16|}}} }} | majority = {{{majority16|}}} | minister = {{{minister16|}}} | minority_leader = {{#if: {{{minorityleader16|}}} | {{{minorityleader16}}} | {{{minority_leader16|}}} }} | monarch = {{{monarch16|}}} | nominator = {{{nominator16|}}} | office = {{{office16|}}} | order = {{{order16|}}} | parliament = {{{parliament16|}}} | parliamentarygroup = {{{parliamentarygroup16|}}} | predecessor = {{{predecessor16|}}} | preceding = {{{preceding16|}}} | preceded = {{{preceded16|}}} | premier = {{{premier16|}}} | president = {{{president16|}}} | primeminister = {{{primeminister16|}}} | riding = {{{riding16|}}} | state_assembly = {{{state_assembly16|}}} | state_delegate = {{{state_delegate16|}}} | state_house = {{{state_house16|}}} | state_legislature = {{{state_legislature16|}}} | state_senate = {{{state_senate16|}}} | state = {{{state16|}}} | status = {{{status16|}}} | subterm = {{{subterm16|}}} | suboffice = {{{suboffice16|}}} | succeeded = {{{succeeded16|}}} | succeeding = {{{succeeding16|}}} | successor = {{{successor16|}}} | taoiseach = {{{taoiseach16|}}} | termlabel = {{{term_label16|{{{termlabel16|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend16|}}}|{{{termend16}}}|{{{term_end16|}}}}} | termstart = {{#if:{{{termstart16|}}}|{{{termstart16}}}|{{{term_start16|}}}}} | term = {{{term16|}}} | title = {{{title16|}}} | vicegovernor = {{{vicegovernor16|}}} | vicepresident = {{{vicepresident16|}}} | vicepremier = {{{vicepremier16|}}} | viceprimeminister = {{{viceprimeminister16|}}} | party = {{{party|}}} | prior_term = {{{prior_term16|}}} }}}} | data2 = {{{module0|}}} <!----------Personal data----------> | header3 = {{#if:{{{pronunciation|}}}{{{birth_name|{{{birthname|}}}}}}{{{birth_date|}}}{{{birth_place|}}}{{{death_date|}}}{{{death_place|}}}{{{resting_place|{{{restingplace|}}}}}}{{{resting_place_coordinates|}}}{{{restingplacecoordinates|}}}{{{burial_place|}}}{{{citizenship|}}}{{{nationality|}}}{{{party|}}}{{{otherparty|}}}{{{spouse|}}}{{{spouses|}}}{{{spouse(s)|}}}{{{partner|}}}{{{relations|}}}{{{children|}}}{{{parents|}}}{{{mother|}}}{{{father|}}}{{{relatives|}}}{{{residence|}}}{{{education|}}}{{{alma_mater|}}}{{{occupation|}}}{{{profession|}}}{{{know for|}}}{{{know_for|}}}{{{known for|}}}{{{known_for|}}}{{{salary|}}}{{{cabinet|}}}{{{committees|}}}{{{portfolio|}}}{{{awards|}}}{{{data1|}}}{{{data2|}}}{{{data3|}}}{{{data4|}}}{{{data5|}}}|ข้อมูลส่วนบุคคล}} | label4 = เสียงอ่าน | data4 = {{{pronunciation|}}} | label5 = เกิด | data5 = {{br separated entries |1 = {{#if:{{{birth_name|{{{birthname|{{{birth name|}}}}}}}}}|<div style="display:inline" class="nickname">{{{birth_name|{{{birthname|{{{birth name}}}}}}}}}</div>}} |2 = {{{birth_date|}}} |3 = {{{birth_place|}}} }} | label6 = เสียชีวิต | data6 = {{br separated entries|{{{death_date|}}}|{{{death_place|}}}}} | label7 = {{#ifexpr: {{strfind short| {{{death_cause|}}}|ถูกลอบสังหาร}} | ลักษณะ |{{#if:{{{death_manner|}}}|ลักษณะ|สาเหตุ}} }}การเสียชีวิต | data7 = {{#if:{{{death_manner|}}}|{{{death_manner|}}}|{{{death_cause|}}}}} | label8 = ที่ไว้ศพ | class8 = label | data8 = {{br separated entries|{{{resting_place|{{{restingplace|{{{burial_place|}}} }}} }}}|{{{resting_place_coordinates|{{{restingplacecoordinates|{{{burial_place|}}} }}} }}}}} | label9 = สัญชาติ | data9 = {{{citizenship|}}} | label10 = เชื้อชาติ | data10 = {{#switch:{{Delink|{{{nationality|}}}}} | {{#ifeq:{{Country2nationality|{{Find country|{{Delink|{{{birth_place|}}}}}}}}}|{{Delink|{{{nationality|}}}}}|{{Delink|{{{nationality|}}}}}}} = | {{#ifeq:{{Find country|{{{birth_place|}}}}}|England|British}} = | #default = {{{nationality|}}} }} | label11 = ศาสนา | data11 = {{{religion|}}} | label12 = พรรคการเมือง | data12 = {{{party|}}} | label13 = {{nowrap|การเข้าร่วม}}<br />{{nowrap|พรรคการเมืองอื่น}} | data13 = {{{otherparty|{{{other_party|}}} }}} | label14 = ความสูง | data14 = {{#if:{{{height|{{{ส่วนสูง|{{{ความสูง|}}} }}} }}}|{{infobox person/height|{{{height|{{{ส่วนสูง|{{{ความสูง|}}} }}} }}}}}}} | label15 = คู่สมรส | data15 = {{{spouse|{{{spouses|{{{spouse(s)|}}}}}}}}} | label16 = คู่อาศัย | data16 = {{{partner|}}} | label17 = ญาติ | data17 = {{{relations|}}} | label18 = บุตร | data18 = {{{children|}}} | label19 = บุพการี | data19 = {{#if:{{{parents|}}}|{{{parents}}}|{{Unbulleted list|{{#if:{{{father|}}}|{{{father}}} (บิดา)}}|{{#if:{{{mother|}}}|{{{mother}}} (มารดา)}}}}}} | label20 = ความสัมพันธ์ | data20 = {{{relatives|}}} | label21 = ที่อยู่อาศัย | class21 = {{#if:{{{death_date|}}}{{{death_place|}}}||label}} | data21 = {{{residence|}}} | label22 = การศึกษา | data22 = {{{education|}}} | label23 = [[โรงเรียนแม่|ศิษย์เก่า]] | data23 = {{{alma_mater|}}} | label24 = อาชีพ | data24= {{{occupation|}}} | label25 = วิชาชีพ | data25 = {{{profession|}}} | label26 = เป็นที่รู้จักจาก | data26 = {{{know for|{{{know_for|{{{known for|{{{known_for|}}} }}} }}} }}} | label27 = เงินเดือน | data27 = {{{salary|}}} | label28 = ทรัพย์สินสุทธิ | data28 = {{{net_worth|}}} | label29 = รัฐบาล | data29 = {{{cabinet|}}} | label30 = คณะกรรมาธิการ | data30 = {{{committees|}}} | label31 = ผลงานเด่น | data31 = {{{portfolio|}}} | label32 = {{#if:{{{mawards|}}}|บำนาญ|รางวัล}} | data32 = {{{awards|}}} | label33 = {{{blank1}}} | data33 = {{{data1|}}} | label34 = {{{blank2}}} | data34 = {{{data2|}}} | label35 = {{{blank3}}} | data35 = {{{data3|}}} | label36 = {{{blank4}}} | data36 = {{{data4|}}} | label37 = {{{blank5}}} | data37 = {{{data5|}}} | label38 = ลายมือชื่อ | data38 = {{#if:{{{signature|}}}|[[File:{{{signature}}}|{{#if:{{{signature_size|}}}|{{{signature_size}}}|128x80px}}|alt={{{signature_alt|}}}|ลายมือชื่อของ{{PAGENAME}}]]}} | label39 = เว็บไซต์ | data39 = {{{website|{{{homepage|}}} }}} | label40 = ชื่อเล่น | data40 = {{{nickname|{{{other_names|{{{othernames|{{{othername|{{{nicknames|}}} }}} }}} }}} }}} | header41 = {{#if:{{{allegiance|}}}{{{branch|}}}{{{serviceyears|}}}{{{rank|}}}{{{unit|}}}{{{commands|}}}{{{battles|}}}{{{wars|}}}{{{battles/wars|}}}{{{military_blank1|}}}|ยศที่ได้รับการแต่งตั้ง}} | label42 = รับใช้ | data42 = {{{allegiance|}}} | label43 = {{#if:{{{branch_label|}}}|{{{branch_label|}}}|สังกัด}} | data43 = {{{branch|}}} | label44 = {{#if:{{{serviceyears_label|}}}|{{{serviceyears_label|}}}|ประจำการ}} | data44 = {{{serviceyears|}}} | label45 = {{#if:{{{rank_label|}}}|{{{rank_label|}}}|ยศ}} | data45 = {{{rank|}}} | label46 = {{#if:{{{unit_label|}}}|{{{unit_label|}}}|หน่วย}} | data46 = {{{unit|}}} | label47 = บังคับบัญชา | data47 = {{{commands|}}} | label48 = {{#if:{{{battles_label|}}}|{{{battles_label|}}}|สงคราม/การสู้รบ}} | data48 = {{{battles|{{{wars|{{{battles/wars|}}} }}} }}} | label49 = {{#if:{{{awards|}}}|บำเหน็จ|รางวัล}} | data49 = {{{mawards|}}} | label50 = {{{military_blank1}}} | data50 = {{{military_data1|}}} | label51 = {{{military_blank2}}} | data51 = {{{military_data2|}}} | label52 = {{{military_blank3}}} | data52 = {{{military_data3|}}} | label53 = {{{military_blank4}}} | data53 = {{{military_data4|}}} | label54 = {{{military_blank5}}} | data54 = {{{military_data5|}}} | data55 = {{{module|}}} | data56 = {{{module2|}}} | data57 = {{{module3|}}} | data58 = {{{module4|}}} | data59 = {{{module5|}}} | data60 = {{{footnotes|}}} | belowstyle = border-top: 1px solid right; font-size: 95% | below = <div>{{#if:{{{date|}}}| ณ วันที่ {{{date}}}{{#if:{{{year|}}}|, {{{year}}}}}}}</div>{{#if:{{{source|}}}|ที่มา: [{{{source}}}]}} }}{{#if:{{{pronunciation|}}}|{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[Category:Biography template using pronunciation]]}} }}{{#if:{{{1blankname0|}}}{{{1namedata0|}}}{{{2blankname0|}}}{{{2namedata0|}}}{{{3blankname0|}}}{{{3namedata0|}}}{{{4blankname0|}}}{{{4namedata0|}}}{{{5blankname0|}}}{{{5namedata0|}}}{{{alongside0|}}}{{{ambassador_from0|}}}{{{appointer0|}}}{{{assembly0|}}}{{{assuming0|}}}{{{chancellor0|}}}{{{co-leader0|}}}{{{constituency_AM0|}}}{{{constituency0|}}}{{{country0|}}}{{{deputy0|}}}{{{district0|}}}{{{firstminister0|}}}{{{governor-general0|}}}{{{governor0|}}}{{{jr/sr0|}}}{{{jr/sr and state0|}}}{{{leader0|}}}{{{legislature0|}}}{{{lieutenant_governor0|}}}{{{lieutenant0|}}}{{{minister_from0|}}}{{{minority_floor_leader0|}}}{{{majority_floor_leader0|}}}{{{majorityleader0|}}}{{{majority0|}}}{{{minister0|}}}{{{minorityleader0|}}}{{{monarch0|}}}{{{nominator0|}}}{{{office0|}}}{{{order0|}}}{{{parliament0|}}}{{{predecessor0|}}}{{{preceding0|}}}{{{preceded0|}}}{{{premier0|}}}{{{president0|}}}{{{primeminister0|}}}{{{riding0|}}}{{{state_assembly0|}}}{{{state_delegate0|}}}{{{state_house0|}}}{{{state_legislature0|}}}{{{state_senate0|}}}{{{state0|}}}{{{suboffice0|}}}{{{subterm0|}}}{{{succeeded0|}}}{{{succeeding0|}}}{{{successor0|}}}{{{taoiseach0|}}}{{{termend0|}}}{{{termstart0|}}}{{{term0|}}}{{{title0|}}}{{{vicegovernor0|}}}{{{vicepresident0|}}}{{{vicepremier0|}}}{{{viceprimeminister0|}}}{{{prior_term0|}}}{{{appointe0|}}}{{{constituency_0|}}}|{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[Category:Pages using infobox officeholder with office0]]}} }}{{#if:{{{speaker|}}}|{{#if:{{{nominee|}}}{{{candidate|}}}||{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[Category:Pages using infobox officeholder with speaker]]}}}} }}{{#invoke:Check for unknown parameters|check|unknown={{main other|{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[หมวดหมู่:หน้าที่ใช้กล่องข้อมูลผู้ดำรงตำแหน่งที่มีพารามิเตอร์ที่ไม่รู้จัก|_VALUE_{{PAGENAME}}]]}}}}|preview=หน้านี้ใช้ [[แม่แบบ:กล่องข้อมูล ผู้ดำรงตำแหน่ง]] ที่มีพารามิเตอร์ที่ไม่รู้จัก "_VALUE_"|ignoreblank=y| regexp1 = 1blankname[%d]* | regexp2 = 1namedata[%d]* | regexp3 = 2blankname[%d]* | regexp4 = 2namedata[%d]* | regexp5 = 3blankname[%d]* | regexp6 = 3namedata[%d]* | regexp7 = 4blankname[%d]* | regexp8 = 4namedata[%d]* | regexp9 = 5blankname[%d]* | regexp10 = 5namedata[%d]* | allegiance | alma_mater | regexp11 = alongside[%d]* | alt | regexp12 = ambassador_from[%d]* | regexp13 = appointed[%d]* | regexp14 = appointer[%d]* | regexp15 = assembly[%d]* | awards | battles | battles/wars | battles_label | birth_date | birth name | birth_name | birth_place | birthname | regexp16 = blank[%d]* | bodyclass | branch | branch_label | burial_place | cabinet | candidate | caption | categories | regexp17 = chancellor[%d]* | children | citizenship | regexp18 = co%-leader[%d]* | commands | committees | regexp19 = constituency[%d]* | regexp20 = constituency_AM[%d]* | regexp21 = constituency_MP[%d]* | regexp22 = convocation[%d]* | regexp23 = country[%d]* | regexp24 = data[%d]* | date | death_cause | death_date | death_manner | death_place | demo | regexp25 = deputy[%d]* | regexp26 = deputyminister[%d]* | regexp27 = district[%d]* | education | election_date | embed | father | regexp28 = firstminister[%d]* | footnotes | regexp29 = governor[%d]* | regexp30 = governor_general[%d]* | regexp31 = governor%-general[%d]* | regexp32 = headminister[%d]* | height | homepage | honorific_prefix | honorific-prefix | honorific_suffix | honorific-suffix | image | image name | image_name_alt | image_size | imagesize | image_upright | incumbent | regexp33 = jr/sr[%d]* | regexp34 = jr/sr and state[%d]* | know for | know_for | known for | known_for | regexp35 = leader[%d]* | regexp36 = legislature[%d]* | regexp37 = lieutenant[%d]* | regexp38 = lieutenant_governor[%d]* | mainwidth | regexp39 = majority[%d]* | regexp40 = majority_floor_leader[%d]* | regexp41 = majority_leader[%d]* | regexp42 = majorityleader[%d]* | mawards | regexp43 = military_blank[%d]* | regexp44 = military_data[%d]* | regexp45 = minister[%d]* | regexp46 = minister_from[%d]* | regexp47 = minority_floor_leader[%d]* | regexp48 = minority_leader[%d]* | regexp49 = minorityleader[%d]* | regexp50 = module[%d]* | regexp51 = monarch[%d]* | mother | name | nationality | native_name | native_name_lang | net_worth | nickname | nicknames | nocat | regexp52 = nominator[%d]* | nominee | occupation | regexp53 = office[%d]* | opponent | regexp54 = order[%d]* | othername | othernames | other_names | otherparty | other_party | parents | regexp55 = parliament[%d]* | regexp56 = parliamentarygroup[%d]* | partner | party | party_election | portfolio | regexp57 = preceded[%d]* | regexp58 = preceding[%d]* | regexp59 = predecessor[%d]* | regexp60 = premier[%d]* | regexp61 = president[%d]* | regexp62 = primeminister[%d]* | regexp63 = prior_term[%d]* | profession | pronunciation | rank | rank_label | relations | relatives | religion | residence | resting_place | resting_place_coordinates | restingplace | restingplacecoordinates | regexp64 = riding[%d]* | runningmate | salary | serviceyears | serviceyears_label | signature | signature_alt | signature_size | smallimage | smallimage_alt | source | speaker | speaker_office | spouse | spouses | spouse(s) | regexp65 = state[%d]* | regexp66 = state_assembly[%d]* | regexp67 = state_delegate[%d]* | regexp68 = state_house[%d]* | regexp69 = state_legislature[%d]* | regexp70 = state_senate[%d]* | regexp71 = status[%d]* | regexp72 = suboffice[%d]* | regexp73 = subterm[%d]* | regexp74 = succeeded[%d]* | regexp75 = succeeding[%d]* | regexp76 = successor[%d]* | regexp77 = taoiseach[%d]* | regexp78 = term[%d]* | regexp79 = term_end[%d]* | regexp80 = term_label[%d]* | regexp81 = term_start[%d]* | regexp82 = termend[%d]* | regexp83 = termlabel[%d]* | regexp84 = termstart[%d]* | regexp85 = title[%d]* | unit | unit_label | regexp86 = vicegovernor[%d]* | regexp87 = vicepremier[%d]* | regexp88 = vicepresident[%d]* | regexp89 = viceprimeminister[%d]* | regexp90 = assuming[%d]* | wars | website | width | year | ความสูง | ส่วนสูง }}<noinclude> {{คู่มือการใช้งาน}} </noinclude> af7d0076064aaf0cf60a58142f848cb5b1e2ac66 มอดูล:Infobox 828 12 19 2023-10-05T10:10:01Z PeachFullzZ 2 สร้างหน้าด้วย "local p = {} local args = {} local origArgs = {} local root local empty_row_categories = {} local category_in_empty_row_pattern = '%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]' local has_rows = false local lists = { plainlist_t = { patterns = { '^plainlist$', '%splainlist$', '^plainlist%s', '%splainlist%s' }, found = false, styles = 'Plainlist/styles.css' }, hlist_t = { patterns = { '^hlist$', '%shlist$', '^hl..." Scribunto text/plain local p = {} local args = {} local origArgs = {} local root local empty_row_categories = {} local category_in_empty_row_pattern = '%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]' local has_rows = false local lists = { plainlist_t = { patterns = { '^plainlist$', '%splainlist$', '^plainlist%s', '%splainlist%s' }, found = false, styles = 'Plainlist/styles.css' }, hlist_t = { patterns = { '^hlist$', '%shlist$', '^hlist%s', '%shlist%s' }, found = false, styles = 'Hlist/styles.css' } } local function has_list_class(args_to_check) for _, list in pairs(lists) do if not list.found then for _, arg in pairs(args_to_check) do for _, pattern in ipairs(list.patterns) do if mw.ustring.find(arg or '', pattern) then list.found = true break end end if list.found then break end end end end end local function fixChildBoxes(sval, tt) local function notempty( s ) return s and s:match( '%S' ) end if notempty(sval) then local marker = '<span class=special_infobox_marker>' local s = sval -- start moving templatestyles and categories inside of table rows local slast = '' while slast ~= s do slast = s s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*%]%])', '%2%1') s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127)', '%2%1') end -- end moving templatestyles and categories inside of table rows s = mw.ustring.gsub(s, '(<%s*[Tt][Rr])', marker .. '%1') s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>)', '%1' .. marker) if s:match(marker) then s = mw.ustring.gsub(s, marker .. '%s*' .. marker, '') s = mw.ustring.gsub(s, '([\r\n]|-[^\r\n]*[\r\n])%s*' .. marker, '%1') s = mw.ustring.gsub(s, marker .. '%s*([\r\n]|-)', '%1') s = mw.ustring.gsub(s, '(</[Cc][Aa][Pp][Tt][Ii][Oo][Nn]%s*>%s*)' .. marker, '%1') s = mw.ustring.gsub(s, '(<%s*[Tt][Aa][Bb][Ll][Ee][^<>]*>%s*)' .. marker, '%1') s = mw.ustring.gsub(s, '^(%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1') s = mw.ustring.gsub(s, '([\r\n]%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1') s = mw.ustring.gsub(s, marker .. '(%s*</[Tt][Aa][Bb][Ll][Ee]%s*>)', '%1') s = mw.ustring.gsub(s, marker .. '(%s*\n|%})', '%1') end if s:match(marker) then local subcells = mw.text.split(s, marker) s = '' for k = 1, #subcells do if k == 1 then s = s .. subcells[k] .. '</' .. tt .. '></tr>' elseif k == #subcells then local rowstyle = ' style="display:none"' if notempty(subcells[k]) then rowstyle = '' end s = s .. '<tr' .. rowstyle ..'><' .. tt .. ' colspan=2>\n' .. subcells[k] elseif notempty(subcells[k]) then if (k % 2) == 0 then s = s .. subcells[k] else s = s .. '<tr><' .. tt .. ' colspan=2>\n' .. subcells[k] .. '</' .. tt .. '></tr>' end end end end -- the next two lines add a newline at the end of lists for the PHP parser -- [[Special:Diff/849054481]] -- remove when [[:phab:T191516]] is fixed or OBE s = mw.ustring.gsub(s, '([\r\n][%*#;:][^\r\n]*)$', '%1\n') s = mw.ustring.gsub(s, '^([%*#;:][^\r\n]*)$', '%1\n') s = mw.ustring.gsub(s, '^([%*#;:])', '\n%1') s = mw.ustring.gsub(s, '^(%{%|)', '\n%1') return s else return sval end end -- Cleans empty tables local function cleanInfobox() root = tostring(root) if has_rows == false then root = mw.ustring.gsub(root, '<table[^<>]*>%s*</table>', '') end end -- Returns the union of the values of two tables, as a sequence. local function union(t1, t2) local vals = {} for k, v in pairs(t1) do vals[v] = true end for k, v in pairs(t2) do vals[v] = true end local ret = {} for k, v in pairs(vals) do table.insert(ret, k) end return ret end -- Returns a table containing the numbers of the arguments that exist -- for the specified prefix. For example, if the prefix was 'data', and -- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}. local function getArgNums(prefix) local nums = {} for k, v in pairs(args) do local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end -- Adds a row to the infobox, with either a header cell -- or a label/data cell combination. local function addRow(rowArgs) if rowArgs.header and rowArgs.header ~= '_BLANK_' then has_rows = true has_list_class({ rowArgs.rowclass, rowArgs.class, args.headerclass }) root :tag('tr') :addClass(rowArgs.rowclass) :cssText(rowArgs.rowstyle) :tag('th') :attr('colspan', '2') :addClass('infobox-header') :addClass(rowArgs.class) :addClass(args.headerclass) -- @deprecated next; target .infobox-<name> .infobox-header :cssText(args.headerstyle) :cssText(rowArgs.rowcellstyle) :wikitext(fixChildBoxes(rowArgs.header, 'th')) if rowArgs.data then root:wikitext( '[[Category:Pages using infobox templates with ignored data cells]]' ) end elseif rowArgs.data and rowArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then has_rows = true has_list_class({ rowArgs.rowclass, rowArgs.class }) local row = root:tag('tr') row:addClass(rowArgs.rowclass) row:cssText(rowArgs.rowstyle) if rowArgs.label then row :tag('th') :attr('scope', 'row') :addClass('infobox-label') -- @deprecated next; target .infobox-<name> .infobox-label :cssText(args.labelstyle) :cssText(rowArgs.rowcellstyle) :wikitext(rowArgs.label) :done() end local dataCell = row:tag('td') dataCell :attr('colspan', not rowArgs.label and '2' or nil) :addClass(not rowArgs.label and 'infobox-full-data' or 'infobox-data') :addClass(rowArgs.class) -- @deprecated next; target .infobox-<name> .infobox(-full)-data :cssText(rowArgs.datastyle) :cssText(rowArgs.rowcellstyle) :wikitext(fixChildBoxes(rowArgs.data, 'td')) else table.insert(empty_row_categories, rowArgs.data or '') end end local function renderTitle() if not args.title then return end has_rows = true has_list_class({args.titleclass}) root :tag('caption') :addClass('infobox-title') :addClass(args.titleclass) -- @deprecated next; target .infobox-<name> .infobox-title :cssText(args.titlestyle) :wikitext(args.title) end local function renderAboveRow() if not args.above then return end has_rows = true has_list_class({ args.aboveclass }) root :tag('tr') :tag('th') :attr('colspan', '2') :addClass('infobox-above') :addClass(args.aboveclass) -- @deprecated next; target .infobox-<name> .infobox-above :cssText(args.abovestyle) :wikitext(fixChildBoxes(args.above,'th')) end local function renderBelowRow() if not args.below then return end has_rows = true has_list_class({ args.belowclass }) root :tag('tr') :tag('td') :attr('colspan', '2') :addClass('infobox-below') :addClass(args.belowclass) -- @deprecated next; target .infobox-<name> .infobox-below :cssText(args.belowstyle) :wikitext(fixChildBoxes(args.below,'td')) end local function addSubheaderRow(subheaderArgs) if subheaderArgs.data and subheaderArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then has_rows = true has_list_class({ subheaderArgs.rowclass, subheaderArgs.class }) local row = root:tag('tr') row:addClass(subheaderArgs.rowclass) local dataCell = row:tag('td') dataCell :attr('colspan', '2') :addClass('infobox-subheader') :addClass(subheaderArgs.class) :cssText(subheaderArgs.datastyle) :cssText(subheaderArgs.rowcellstyle) :wikitext(fixChildBoxes(subheaderArgs.data, 'td')) else table.insert(empty_row_categories, subheaderArgs.data or '') end end local function renderSubheaders() if args.subheader then args.subheader1 = args.subheader end if args.subheaderrowclass then args.subheaderrowclass1 = args.subheaderrowclass end local subheadernums = getArgNums('subheader') for k, num in ipairs(subheadernums) do addSubheaderRow({ data = args['subheader' .. tostring(num)], -- @deprecated next; target .infobox-<name> .infobox-subheader datastyle = args.subheaderstyle, rowcellstyle = args['subheaderstyle' .. tostring(num)], class = args.subheaderclass, rowclass = args['subheaderrowclass' .. tostring(num)] }) end end local function addImageRow(imageArgs) if imageArgs.data and imageArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then has_rows = true has_list_class({ imageArgs.rowclass, imageArgs.class }) local row = root:tag('tr') row:addClass(imageArgs.rowclass) local dataCell = row:tag('td') dataCell :attr('colspan', '2') :addClass('infobox-image') :addClass(imageArgs.class) :cssText(imageArgs.datastyle) :wikitext(fixChildBoxes(imageArgs.data, 'td')) else table.insert(empty_row_categories, imageArgs.data or '') end end local function renderImages() if args.image then args.image1 = args.image end if args.caption then args.caption1 = args.caption end local imagenums = getArgNums('image') for k, num in ipairs(imagenums) do local caption = args['caption' .. tostring(num)] local data = mw.html.create():wikitext(args['image' .. tostring(num)]) if caption then data :tag('div') :addClass('infobox-caption') -- @deprecated next; target .infobox-<name> .infobox-caption :cssText(args.captionstyle) :wikitext(caption) end addImageRow({ data = tostring(data), -- @deprecated next; target .infobox-<name> .infobox-image datastyle = args.imagestyle, class = args.imageclass, rowclass = args['imagerowclass' .. tostring(num)] }) end end -- When autoheaders are turned on, preprocesses the rows local function preprocessRows() if not args.autoheaders then return end local rownums = union(getArgNums('header'), getArgNums('data')) table.sort(rownums) local lastheader for k, num in ipairs(rownums) do if args['header' .. tostring(num)] then if lastheader then args['header' .. tostring(lastheader)] = nil end lastheader = num elseif args['data' .. tostring(num)] and args['data' .. tostring(num)]:gsub( category_in_empty_row_pattern, '' ):match('^%S') then local data = args['data' .. tostring(num)] if data:gsub(category_in_empty_row_pattern, ''):match('%S') then lastheader = nil end end end if lastheader then args['header' .. tostring(lastheader)] = nil end end -- Gets the union of the header and data argument numbers, -- and renders them all in order local function renderRows() local rownums = union(getArgNums('header'), getArgNums('data')) table.sort(rownums) for k, num in ipairs(rownums) do addRow({ header = args['header' .. tostring(num)], label = args['label' .. tostring(num)], data = args['data' .. tostring(num)], datastyle = args.datastyle, class = args['class' .. tostring(num)], rowclass = args['rowclass' .. tostring(num)], -- @deprecated next; target .infobox-<name> rowclass rowstyle = args['rowstyle' .. tostring(num)], rowcellstyle = args['rowcellstyle' .. tostring(num)] }) end end local function renderNavBar() if not args.name then return end has_rows = true root :tag('tr') :tag('td') :attr('colspan', '2') :addClass('infobox-navbar') :wikitext(require('Module:Navbar')._navbar{ args.name, mini = 1, }) end local function renderItalicTitle() local italicTitle = args['italic title'] and mw.ustring.lower(args['italic title']) if italicTitle == '' or italicTitle == 'force' or italicTitle == 'yes' then root:wikitext(require('Module:Italic title')._main({})) end end -- Categories in otherwise empty rows are collected in empty_row_categories. -- This function adds them to the module output. It is not affected by -- args.decat because this module should not prevent module-external categories -- from rendering. local function renderEmptyRowCategories() for _, s in ipairs(empty_row_categories) do root:wikitext(s) end end -- Render tracking categories. args.decat == turns off tracking categories. local function renderTrackingCategories() if args.decat == 'yes' then return end if args.child == 'yes' then if args.title then root:wikitext( '[[Category:Pages using embedded infobox templates with the title parameter]]' ) end elseif #(getArgNums('data')) == 0 and mw.title.getCurrentTitle().namespace == 0 then root:wikitext('[[Category:Articles using infobox templates with no data rows]]') end end --[=[ Loads the templatestyles for the infobox. TODO: FINISH loading base templatestyles here rather than in MediaWiki:Common.css. There are 4-5000 pages with 'raw' infobox tables. See [[Mediawiki_talk:Common.css/to_do#Infobox]] and/or come help :). When we do this we should clean up the inline CSS below too. Will have to do some bizarre conversion category like with sidebar. ]=] local function loadTemplateStyles() local frame = mw.getCurrentFrame() local hlist_templatestyles = '' if lists.hlist_t.found then hlist_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = lists.hlist_t.styles } } end local plainlist_templatestyles = '' if lists.plainlist_t.found then plainlist_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = lists.plainlist_t.styles } } end -- See function description local base_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = 'Module:Infobox/styles.css' } } local templatestyles = '' if args['templatestyles'] then templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = args['templatestyles'] } } end local child_templatestyles = '' if args['child templatestyles'] then child_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = args['child templatestyles'] } } end local grandchild_templatestyles = '' if args['grandchild templatestyles'] then grandchild_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = args['grandchild templatestyles'] } } end return table.concat({ -- hlist -> plainlist -> base is best-effort to preserve old Common.css ordering. -- this ordering is not a guarantee because the rows of interest invoking -- each class may not be on a specific page hlist_templatestyles, plainlist_templatestyles, base_templatestyles, templatestyles, child_templatestyles, grandchild_templatestyles }) end -- common functions between the child and non child cases local function structure_infobox_common() renderSubheaders() renderImages() preprocessRows() renderRows() renderBelowRow() renderNavBar() renderItalicTitle() renderEmptyRowCategories() renderTrackingCategories() cleanInfobox() end -- Specify the overall layout of the infobox, with special settings if the -- infobox is used as a 'child' inside another infobox. local function _infobox() if args.child ~= 'yes' then root = mw.html.create('table') root :addClass(args.subbox == 'yes' and 'infobox-subbox' or 'infobox') :addClass(args.bodyclass) -- @deprecated next; target .infobox-<name> :cssText(args.bodystyle) has_list_class({ args.bodyclass }) renderTitle() renderAboveRow() else root = mw.html.create() root :wikitext(args.title) end structure_infobox_common() return loadTemplateStyles() .. root end -- If the argument exists and isn't blank, add it to the argument table. -- Blank arguments are treated as nil to match the behaviour of ParserFunctions. local function preprocessSingleArg(argName) if origArgs[argName] and origArgs[argName] ~= '' then args[argName] = origArgs[argName] end end -- Assign the parameters with the given prefixes to the args table, in order, in -- batches of the step size specified. This is to prevent references etc. from -- appearing in the wrong order. The prefixTable should be an array containing -- tables, each of which has two possible fields, a "prefix" string and a -- "depend" table. The function always parses parameters containing the "prefix" -- string, but only parses parameters in the "depend" table if the prefix -- parameter is present and non-blank. local function preprocessArgs(prefixTable, step) if type(prefixTable) ~= 'table' then error("Non-table value detected for the prefix table", 2) end if type(step) ~= 'number' then error("Invalid step value detected", 2) end -- Get arguments without a number suffix, and check for bad input. for i,v in ipairs(prefixTable) do if type(v) ~= 'table' or type(v.prefix) ~= "string" or (v.depend and type(v.depend) ~= 'table') then error('Invalid input detected to preprocessArgs prefix table', 2) end preprocessSingleArg(v.prefix) -- Only parse the depend parameter if the prefix parameter is present -- and not blank. if args[v.prefix] and v.depend then for j, dependValue in ipairs(v.depend) do if type(dependValue) ~= 'string' then error('Invalid "depend" parameter value detected in preprocessArgs') end preprocessSingleArg(dependValue) end end end -- Get arguments with number suffixes. local a = 1 -- Counter variable. local moreArgumentsExist = true while moreArgumentsExist == true do moreArgumentsExist = false for i = a, a + step - 1 do for j,v in ipairs(prefixTable) do local prefixArgName = v.prefix .. tostring(i) if origArgs[prefixArgName] then -- Do another loop if any arguments are found, even blank ones. moreArgumentsExist = true preprocessSingleArg(prefixArgName) end -- Process the depend table if the prefix argument is present -- and not blank, or we are processing "prefix1" and "prefix" is -- present and not blank, and if the depend table is present. if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then for j,dependValue in ipairs(v.depend) do local dependArgName = dependValue .. tostring(i) preprocessSingleArg(dependArgName) end end end end a = a + step end end -- Parse the data parameters in the same order that the old {{infobox}} did, so -- that references etc. will display in the expected places. Parameters that -- depend on another parameter are only processed if that parameter is present, -- to avoid phantom references appearing in article reference lists. local function parseDataParameters() preprocessSingleArg('autoheaders') preprocessSingleArg('child') preprocessSingleArg('bodyclass') preprocessSingleArg('subbox') preprocessSingleArg('bodystyle') preprocessSingleArg('title') preprocessSingleArg('titleclass') preprocessSingleArg('titlestyle') preprocessSingleArg('above') preprocessSingleArg('aboveclass') preprocessSingleArg('abovestyle') preprocessArgs({ {prefix = 'subheader', depend = {'subheaderstyle', 'subheaderrowclass'}} }, 10) preprocessSingleArg('subheaderstyle') preprocessSingleArg('subheaderclass') preprocessArgs({ {prefix = 'image', depend = {'caption', 'imagerowclass'}} }, 10) preprocessSingleArg('captionstyle') preprocessSingleArg('imagestyle') preprocessSingleArg('imageclass') preprocessArgs({ {prefix = 'header'}, {prefix = 'data', depend = {'label'}}, {prefix = 'rowclass'}, {prefix = 'rowstyle'}, {prefix = 'rowcellstyle'}, {prefix = 'class'} }, 50) preprocessSingleArg('headerclass') preprocessSingleArg('headerstyle') preprocessSingleArg('labelstyle') preprocessSingleArg('datastyle') preprocessSingleArg('below') preprocessSingleArg('belowclass') preprocessSingleArg('belowstyle') preprocessSingleArg('name') -- different behaviour for italics if blank or absent args['italic title'] = origArgs['italic title'] preprocessSingleArg('decat') preprocessSingleArg('templatestyles') preprocessSingleArg('child templatestyles') preprocessSingleArg('grandchild templatestyles') end -- If called via #invoke, use the args passed into the invoking template. -- Otherwise, for testing purposes, assume args are being passed directly in. function p.infobox(frame) if frame == mw.getCurrentFrame() then origArgs = frame:getParent().args else origArgs = frame end parseDataParameters() return _infobox() end -- For calling via #invoke within a template function p.infoboxTemplate(frame) origArgs = {} for k,v in pairs(frame.args) do origArgs[k] = mw.text.trim(v) end parseDataParameters() return _infobox() end return p 0ddb7e5c8426d67cd589b710efb9912ddfb67fea 20 19 2023-10-05T10:10:19Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Infobox]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local p = {} local args = {} local origArgs = {} local root local empty_row_categories = {} local category_in_empty_row_pattern = '%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]' local has_rows = false local lists = { plainlist_t = { patterns = { '^plainlist$', '%splainlist$', '^plainlist%s', '%splainlist%s' }, found = false, styles = 'Plainlist/styles.css' }, hlist_t = { patterns = { '^hlist$', '%shlist$', '^hlist%s', '%shlist%s' }, found = false, styles = 'Hlist/styles.css' } } local function has_list_class(args_to_check) for _, list in pairs(lists) do if not list.found then for _, arg in pairs(args_to_check) do for _, pattern in ipairs(list.patterns) do if mw.ustring.find(arg or '', pattern) then list.found = true break end end if list.found then break end end end end end local function fixChildBoxes(sval, tt) local function notempty( s ) return s and s:match( '%S' ) end if notempty(sval) then local marker = '<span class=special_infobox_marker>' local s = sval -- start moving templatestyles and categories inside of table rows local slast = '' while slast ~= s do slast = s s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*%]%])', '%2%1') s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127)', '%2%1') end -- end moving templatestyles and categories inside of table rows s = mw.ustring.gsub(s, '(<%s*[Tt][Rr])', marker .. '%1') s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>)', '%1' .. marker) if s:match(marker) then s = mw.ustring.gsub(s, marker .. '%s*' .. marker, '') s = mw.ustring.gsub(s, '([\r\n]|-[^\r\n]*[\r\n])%s*' .. marker, '%1') s = mw.ustring.gsub(s, marker .. '%s*([\r\n]|-)', '%1') s = mw.ustring.gsub(s, '(</[Cc][Aa][Pp][Tt][Ii][Oo][Nn]%s*>%s*)' .. marker, '%1') s = mw.ustring.gsub(s, '(<%s*[Tt][Aa][Bb][Ll][Ee][^<>]*>%s*)' .. marker, '%1') s = mw.ustring.gsub(s, '^(%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1') s = mw.ustring.gsub(s, '([\r\n]%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1') s = mw.ustring.gsub(s, marker .. '(%s*</[Tt][Aa][Bb][Ll][Ee]%s*>)', '%1') s = mw.ustring.gsub(s, marker .. '(%s*\n|%})', '%1') end if s:match(marker) then local subcells = mw.text.split(s, marker) s = '' for k = 1, #subcells do if k == 1 then s = s .. subcells[k] .. '</' .. tt .. '></tr>' elseif k == #subcells then local rowstyle = ' style="display:none"' if notempty(subcells[k]) then rowstyle = '' end s = s .. '<tr' .. rowstyle ..'><' .. tt .. ' colspan=2>\n' .. subcells[k] elseif notempty(subcells[k]) then if (k % 2) == 0 then s = s .. subcells[k] else s = s .. '<tr><' .. tt .. ' colspan=2>\n' .. subcells[k] .. '</' .. tt .. '></tr>' end end end end -- the next two lines add a newline at the end of lists for the PHP parser -- [[Special:Diff/849054481]] -- remove when [[:phab:T191516]] is fixed or OBE s = mw.ustring.gsub(s, '([\r\n][%*#;:][^\r\n]*)$', '%1\n') s = mw.ustring.gsub(s, '^([%*#;:][^\r\n]*)$', '%1\n') s = mw.ustring.gsub(s, '^([%*#;:])', '\n%1') s = mw.ustring.gsub(s, '^(%{%|)', '\n%1') return s else return sval end end -- Cleans empty tables local function cleanInfobox() root = tostring(root) if has_rows == false then root = mw.ustring.gsub(root, '<table[^<>]*>%s*</table>', '') end end -- Returns the union of the values of two tables, as a sequence. local function union(t1, t2) local vals = {} for k, v in pairs(t1) do vals[v] = true end for k, v in pairs(t2) do vals[v] = true end local ret = {} for k, v in pairs(vals) do table.insert(ret, k) end return ret end -- Returns a table containing the numbers of the arguments that exist -- for the specified prefix. For example, if the prefix was 'data', and -- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}. local function getArgNums(prefix) local nums = {} for k, v in pairs(args) do local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end -- Adds a row to the infobox, with either a header cell -- or a label/data cell combination. local function addRow(rowArgs) if rowArgs.header and rowArgs.header ~= '_BLANK_' then has_rows = true has_list_class({ rowArgs.rowclass, rowArgs.class, args.headerclass }) root :tag('tr') :addClass(rowArgs.rowclass) :cssText(rowArgs.rowstyle) :tag('th') :attr('colspan', '2') :addClass('infobox-header') :addClass(rowArgs.class) :addClass(args.headerclass) -- @deprecated next; target .infobox-<name> .infobox-header :cssText(args.headerstyle) :cssText(rowArgs.rowcellstyle) :wikitext(fixChildBoxes(rowArgs.header, 'th')) if rowArgs.data then root:wikitext( '[[Category:Pages using infobox templates with ignored data cells]]' ) end elseif rowArgs.data and rowArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then has_rows = true has_list_class({ rowArgs.rowclass, rowArgs.class }) local row = root:tag('tr') row:addClass(rowArgs.rowclass) row:cssText(rowArgs.rowstyle) if rowArgs.label then row :tag('th') :attr('scope', 'row') :addClass('infobox-label') -- @deprecated next; target .infobox-<name> .infobox-label :cssText(args.labelstyle) :cssText(rowArgs.rowcellstyle) :wikitext(rowArgs.label) :done() end local dataCell = row:tag('td') dataCell :attr('colspan', not rowArgs.label and '2' or nil) :addClass(not rowArgs.label and 'infobox-full-data' or 'infobox-data') :addClass(rowArgs.class) -- @deprecated next; target .infobox-<name> .infobox(-full)-data :cssText(rowArgs.datastyle) :cssText(rowArgs.rowcellstyle) :wikitext(fixChildBoxes(rowArgs.data, 'td')) else table.insert(empty_row_categories, rowArgs.data or '') end end local function renderTitle() if not args.title then return end has_rows = true has_list_class({args.titleclass}) root :tag('caption') :addClass('infobox-title') :addClass(args.titleclass) -- @deprecated next; target .infobox-<name> .infobox-title :cssText(args.titlestyle) :wikitext(args.title) end local function renderAboveRow() if not args.above then return end has_rows = true has_list_class({ args.aboveclass }) root :tag('tr') :tag('th') :attr('colspan', '2') :addClass('infobox-above') :addClass(args.aboveclass) -- @deprecated next; target .infobox-<name> .infobox-above :cssText(args.abovestyle) :wikitext(fixChildBoxes(args.above,'th')) end local function renderBelowRow() if not args.below then return end has_rows = true has_list_class({ args.belowclass }) root :tag('tr') :tag('td') :attr('colspan', '2') :addClass('infobox-below') :addClass(args.belowclass) -- @deprecated next; target .infobox-<name> .infobox-below :cssText(args.belowstyle) :wikitext(fixChildBoxes(args.below,'td')) end local function addSubheaderRow(subheaderArgs) if subheaderArgs.data and subheaderArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then has_rows = true has_list_class({ subheaderArgs.rowclass, subheaderArgs.class }) local row = root:tag('tr') row:addClass(subheaderArgs.rowclass) local dataCell = row:tag('td') dataCell :attr('colspan', '2') :addClass('infobox-subheader') :addClass(subheaderArgs.class) :cssText(subheaderArgs.datastyle) :cssText(subheaderArgs.rowcellstyle) :wikitext(fixChildBoxes(subheaderArgs.data, 'td')) else table.insert(empty_row_categories, subheaderArgs.data or '') end end local function renderSubheaders() if args.subheader then args.subheader1 = args.subheader end if args.subheaderrowclass then args.subheaderrowclass1 = args.subheaderrowclass end local subheadernums = getArgNums('subheader') for k, num in ipairs(subheadernums) do addSubheaderRow({ data = args['subheader' .. tostring(num)], -- @deprecated next; target .infobox-<name> .infobox-subheader datastyle = args.subheaderstyle, rowcellstyle = args['subheaderstyle' .. tostring(num)], class = args.subheaderclass, rowclass = args['subheaderrowclass' .. tostring(num)] }) end end local function addImageRow(imageArgs) if imageArgs.data and imageArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then has_rows = true has_list_class({ imageArgs.rowclass, imageArgs.class }) local row = root:tag('tr') row:addClass(imageArgs.rowclass) local dataCell = row:tag('td') dataCell :attr('colspan', '2') :addClass('infobox-image') :addClass(imageArgs.class) :cssText(imageArgs.datastyle) :wikitext(fixChildBoxes(imageArgs.data, 'td')) else table.insert(empty_row_categories, imageArgs.data or '') end end local function renderImages() if args.image then args.image1 = args.image end if args.caption then args.caption1 = args.caption end local imagenums = getArgNums('image') for k, num in ipairs(imagenums) do local caption = args['caption' .. tostring(num)] local data = mw.html.create():wikitext(args['image' .. tostring(num)]) if caption then data :tag('div') :addClass('infobox-caption') -- @deprecated next; target .infobox-<name> .infobox-caption :cssText(args.captionstyle) :wikitext(caption) end addImageRow({ data = tostring(data), -- @deprecated next; target .infobox-<name> .infobox-image datastyle = args.imagestyle, class = args.imageclass, rowclass = args['imagerowclass' .. tostring(num)] }) end end -- When autoheaders are turned on, preprocesses the rows local function preprocessRows() if not args.autoheaders then return end local rownums = union(getArgNums('header'), getArgNums('data')) table.sort(rownums) local lastheader for k, num in ipairs(rownums) do if args['header' .. tostring(num)] then if lastheader then args['header' .. tostring(lastheader)] = nil end lastheader = num elseif args['data' .. tostring(num)] and args['data' .. tostring(num)]:gsub( category_in_empty_row_pattern, '' ):match('^%S') then local data = args['data' .. tostring(num)] if data:gsub(category_in_empty_row_pattern, ''):match('%S') then lastheader = nil end end end if lastheader then args['header' .. tostring(lastheader)] = nil end end -- Gets the union of the header and data argument numbers, -- and renders them all in order local function renderRows() local rownums = union(getArgNums('header'), getArgNums('data')) table.sort(rownums) for k, num in ipairs(rownums) do addRow({ header = args['header' .. tostring(num)], label = args['label' .. tostring(num)], data = args['data' .. tostring(num)], datastyle = args.datastyle, class = args['class' .. tostring(num)], rowclass = args['rowclass' .. tostring(num)], -- @deprecated next; target .infobox-<name> rowclass rowstyle = args['rowstyle' .. tostring(num)], rowcellstyle = args['rowcellstyle' .. tostring(num)] }) end end local function renderNavBar() if not args.name then return end has_rows = true root :tag('tr') :tag('td') :attr('colspan', '2') :addClass('infobox-navbar') :wikitext(require('Module:Navbar')._navbar{ args.name, mini = 1, }) end local function renderItalicTitle() local italicTitle = args['italic title'] and mw.ustring.lower(args['italic title']) if italicTitle == '' or italicTitle == 'force' or italicTitle == 'yes' then root:wikitext(require('Module:Italic title')._main({})) end end -- Categories in otherwise empty rows are collected in empty_row_categories. -- This function adds them to the module output. It is not affected by -- args.decat because this module should not prevent module-external categories -- from rendering. local function renderEmptyRowCategories() for _, s in ipairs(empty_row_categories) do root:wikitext(s) end end -- Render tracking categories. args.decat == turns off tracking categories. local function renderTrackingCategories() if args.decat == 'yes' then return end if args.child == 'yes' then if args.title then root:wikitext( '[[Category:Pages using embedded infobox templates with the title parameter]]' ) end elseif #(getArgNums('data')) == 0 and mw.title.getCurrentTitle().namespace == 0 then root:wikitext('[[Category:Articles using infobox templates with no data rows]]') end end --[=[ Loads the templatestyles for the infobox. TODO: FINISH loading base templatestyles here rather than in MediaWiki:Common.css. There are 4-5000 pages with 'raw' infobox tables. See [[Mediawiki_talk:Common.css/to_do#Infobox]] and/or come help :). When we do this we should clean up the inline CSS below too. Will have to do some bizarre conversion category like with sidebar. ]=] local function loadTemplateStyles() local frame = mw.getCurrentFrame() local hlist_templatestyles = '' if lists.hlist_t.found then hlist_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = lists.hlist_t.styles } } end local plainlist_templatestyles = '' if lists.plainlist_t.found then plainlist_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = lists.plainlist_t.styles } } end -- See function description local base_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = 'Module:Infobox/styles.css' } } local templatestyles = '' if args['templatestyles'] then templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = args['templatestyles'] } } end local child_templatestyles = '' if args['child templatestyles'] then child_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = args['child templatestyles'] } } end local grandchild_templatestyles = '' if args['grandchild templatestyles'] then grandchild_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = args['grandchild templatestyles'] } } end return table.concat({ -- hlist -> plainlist -> base is best-effort to preserve old Common.css ordering. -- this ordering is not a guarantee because the rows of interest invoking -- each class may not be on a specific page hlist_templatestyles, plainlist_templatestyles, base_templatestyles, templatestyles, child_templatestyles, grandchild_templatestyles }) end -- common functions between the child and non child cases local function structure_infobox_common() renderSubheaders() renderImages() preprocessRows() renderRows() renderBelowRow() renderNavBar() renderItalicTitle() renderEmptyRowCategories() renderTrackingCategories() cleanInfobox() end -- Specify the overall layout of the infobox, with special settings if the -- infobox is used as a 'child' inside another infobox. local function _infobox() if args.child ~= 'yes' then root = mw.html.create('table') root :addClass(args.subbox == 'yes' and 'infobox-subbox' or 'infobox') :addClass(args.bodyclass) -- @deprecated next; target .infobox-<name> :cssText(args.bodystyle) has_list_class({ args.bodyclass }) renderTitle() renderAboveRow() else root = mw.html.create() root :wikitext(args.title) end structure_infobox_common() return loadTemplateStyles() .. root end -- If the argument exists and isn't blank, add it to the argument table. -- Blank arguments are treated as nil to match the behaviour of ParserFunctions. local function preprocessSingleArg(argName) if origArgs[argName] and origArgs[argName] ~= '' then args[argName] = origArgs[argName] end end -- Assign the parameters with the given prefixes to the args table, in order, in -- batches of the step size specified. This is to prevent references etc. from -- appearing in the wrong order. The prefixTable should be an array containing -- tables, each of which has two possible fields, a "prefix" string and a -- "depend" table. The function always parses parameters containing the "prefix" -- string, but only parses parameters in the "depend" table if the prefix -- parameter is present and non-blank. local function preprocessArgs(prefixTable, step) if type(prefixTable) ~= 'table' then error("Non-table value detected for the prefix table", 2) end if type(step) ~= 'number' then error("Invalid step value detected", 2) end -- Get arguments without a number suffix, and check for bad input. for i,v in ipairs(prefixTable) do if type(v) ~= 'table' or type(v.prefix) ~= "string" or (v.depend and type(v.depend) ~= 'table') then error('Invalid input detected to preprocessArgs prefix table', 2) end preprocessSingleArg(v.prefix) -- Only parse the depend parameter if the prefix parameter is present -- and not blank. if args[v.prefix] and v.depend then for j, dependValue in ipairs(v.depend) do if type(dependValue) ~= 'string' then error('Invalid "depend" parameter value detected in preprocessArgs') end preprocessSingleArg(dependValue) end end end -- Get arguments with number suffixes. local a = 1 -- Counter variable. local moreArgumentsExist = true while moreArgumentsExist == true do moreArgumentsExist = false for i = a, a + step - 1 do for j,v in ipairs(prefixTable) do local prefixArgName = v.prefix .. tostring(i) if origArgs[prefixArgName] then -- Do another loop if any arguments are found, even blank ones. moreArgumentsExist = true preprocessSingleArg(prefixArgName) end -- Process the depend table if the prefix argument is present -- and not blank, or we are processing "prefix1" and "prefix" is -- present and not blank, and if the depend table is present. if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then for j,dependValue in ipairs(v.depend) do local dependArgName = dependValue .. tostring(i) preprocessSingleArg(dependArgName) end end end end a = a + step end end -- Parse the data parameters in the same order that the old {{infobox}} did, so -- that references etc. will display in the expected places. Parameters that -- depend on another parameter are only processed if that parameter is present, -- to avoid phantom references appearing in article reference lists. local function parseDataParameters() preprocessSingleArg('autoheaders') preprocessSingleArg('child') preprocessSingleArg('bodyclass') preprocessSingleArg('subbox') preprocessSingleArg('bodystyle') preprocessSingleArg('title') preprocessSingleArg('titleclass') preprocessSingleArg('titlestyle') preprocessSingleArg('above') preprocessSingleArg('aboveclass') preprocessSingleArg('abovestyle') preprocessArgs({ {prefix = 'subheader', depend = {'subheaderstyle', 'subheaderrowclass'}} }, 10) preprocessSingleArg('subheaderstyle') preprocessSingleArg('subheaderclass') preprocessArgs({ {prefix = 'image', depend = {'caption', 'imagerowclass'}} }, 10) preprocessSingleArg('captionstyle') preprocessSingleArg('imagestyle') preprocessSingleArg('imageclass') preprocessArgs({ {prefix = 'header'}, {prefix = 'data', depend = {'label'}}, {prefix = 'rowclass'}, {prefix = 'rowstyle'}, {prefix = 'rowcellstyle'}, {prefix = 'class'} }, 50) preprocessSingleArg('headerclass') preprocessSingleArg('headerstyle') preprocessSingleArg('labelstyle') preprocessSingleArg('datastyle') preprocessSingleArg('below') preprocessSingleArg('belowclass') preprocessSingleArg('belowstyle') preprocessSingleArg('name') -- different behaviour for italics if blank or absent args['italic title'] = origArgs['italic title'] preprocessSingleArg('decat') preprocessSingleArg('templatestyles') preprocessSingleArg('child templatestyles') preprocessSingleArg('grandchild templatestyles') end -- If called via #invoke, use the args passed into the invoking template. -- Otherwise, for testing purposes, assume args are being passed directly in. function p.infobox(frame) if frame == mw.getCurrentFrame() then origArgs = frame:getParent().args else origArgs = frame end parseDataParameters() return _infobox() end -- For calling via #invoke within a template function p.infoboxTemplate(frame) origArgs = {} for k,v in pairs(frame.args) do origArgs[k] = mw.text.trim(v) end parseDataParameters() return _infobox() end return p 0ddb7e5c8426d67cd589b710efb9912ddfb67fea แม่แบบ:Pp 10 13 21 2023-10-05T10:15:46Z PeachFullzZ 2 สร้างหน้าด้วย "{{#invoke:Protection banner|main}}<noinclude> {{documentation}} </noinclude>" wikitext text/x-wiki {{#invoke:Protection banner|main}}<noinclude> {{documentation}} </noinclude> 4b195ffc44cfde864ef77b55a54c006333226ced มอดูล:Infobox/styles.css 828 14 22 2023-10-05T10:24:35Z PeachFullzZ 2 สร้างหน้าด้วย "/* {{pp|small=y}} */ /* * This TemplateStyles sheet deliberately does NOT include the full set of * infobox styles. We are still working to migrate all of the manual * infoboxes. See [[MediaWiki talk:Common.css/to do#Infobox]] * DO NOT ADD THEM HERE */ /* * not strictly certain these styles are necessary since the modules now * exclusively output infobox-subbox or infobox, not both * just replicating the module faithfully */ .infobox-subbox..." sanitized-css text/css /* {{pp|small=y}} */ /* * This TemplateStyles sheet deliberately does NOT include the full set of * infobox styles. We are still working to migrate all of the manual * infoboxes. See [[MediaWiki talk:Common.css/to do#Infobox]] * DO NOT ADD THEM HERE */ /* * not strictly certain these styles are necessary since the modules now * exclusively output infobox-subbox or infobox, not both * just replicating the module faithfully */ .infobox-subbox { padding: 0; border: none; margin: -3px; width: auto; min-width: 100%; font-size: 100%; clear: none; float: none; background-color: transparent; } .infobox-3cols-child { margin: auto; } .infobox .navbar { font-size: 100%; } /* T281642 */ body.skin-minerva .infobox-header, body.skin-minerva .infobox-subheader, body.skin-minerva .infobox-above, body.skin-minerva .infobox-title, body.skin-minerva .infobox-image, body.skin-minerva .infobox-full-data, body.skin-minerva .infobox-below { text-align: center; } e8de6d96f4fde53afc4a6b0fed534405ab59b0a7 23 22 2023-10-05T10:27:07Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Infobox/styles.css]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) sanitized-css text/css /* {{pp|small=y}} */ /* * This TemplateStyles sheet deliberately does NOT include the full set of * infobox styles. We are still working to migrate all of the manual * infoboxes. See [[MediaWiki talk:Common.css/to do#Infobox]] * DO NOT ADD THEM HERE */ /* * not strictly certain these styles are necessary since the modules now * exclusively output infobox-subbox or infobox, not both * just replicating the module faithfully */ .infobox-subbox { padding: 0; border: none; margin: -3px; width: auto; min-width: 100%; font-size: 100%; clear: none; float: none; background-color: transparent; } .infobox-3cols-child { margin: auto; } .infobox .navbar { font-size: 100%; } /* T281642 */ body.skin-minerva .infobox-header, body.skin-minerva .infobox-subheader, body.skin-minerva .infobox-above, body.skin-minerva .infobox-title, body.skin-minerva .infobox-image, body.skin-minerva .infobox-full-data, body.skin-minerva .infobox-below { text-align: center; } e8de6d96f4fde53afc4a6b0fed534405ab59b0a7 มอดูล:InfoboxImage 828 15 24 2023-10-05T10:27:31Z PeachFullzZ 2 สร้างหน้าด้วย "-- Inputs: -- image - Can either be a bare filename (with or without the File:/Image: prefix) or a fully formatted image link -- page - page to display for multipage images (DjVu) -- size - size to display the image -- maxsize - maximum size for image -- sizedefault - default size to display the image if size param is blank -- alt - alt text for image -- title - title text for image -- border - set to yes if border -- cent..." Scribunto text/plain -- Inputs: -- image - Can either be a bare filename (with or without the File:/Image: prefix) or a fully formatted image link -- page - page to display for multipage images (DjVu) -- size - size to display the image -- maxsize - maximum size for image -- sizedefault - default size to display the image if size param is blank -- alt - alt text for image -- title - title text for image -- border - set to yes if border -- center - set to yes, if the image has to be centered -- upright - upright image param -- suppressplaceholder - if yes then checks to see if image is a placeholder and suppresses it -- link - page to visit when clicking on image -- class - HTML classes to add to the image -- Outputs: -- Formatted image. -- More details available at the "Module:InfoboxImage/doc" page local i = {}; local placeholder_image = { "Blue - Replace this image female.svg", "Blue - Replace this image male.svg", "Female no free image yet.png", "Flag of None (square).svg", "Flag of None.svg", "Flag of.svg", "Green - Replace this image female.svg", "Green - Replace this image male.svg", "Image is needed female.svg", "Image is needed male.svg", "Location map of None.svg", "Male no free image yet.png", "Missing flag.png", "No flag.svg", "No free portrait.svg", "No portrait (female).svg", "No portrait (male).svg", "Red - Replace this image female.svg", "Red - Replace this image male.svg", "Replace this image female (blue).svg", "Replace this image female.svg", "Replace this image male (blue).svg", "Replace this image male.svg", "Silver - Replace this image female.svg", "Silver - Replace this image male.svg", "Replace this image.svg", "Cricket no pic.png", "CarersLogo.gif", "Diagram Needed.svg", "Example.jpg", "Image placeholder.png", "No male portrait.svg", "Nocover-upload.png", "NoDVDcover copy.png", "Noribbon.svg", "No portrait-BFD-test.svg", "Placeholder barnstar ribbon.png", "Project Trains no image.png", "Image-request.png", "Sin bandera.svg", "Sin escudo.svg", "Replace this image - temple.png", "Replace this image butterfly.png", "Replace this image.svg", "Replace this image1.svg", "Resolution angle.png", "Image-No portrait-text-BFD-test.svg", "Insert image here.svg", "No image available.png", "NO IMAGE YET square.png", "NO IMAGE YET.png", "No Photo Available.svg", "No Screenshot.svg", "No-image-available.jpg", "Null.png", "PictureNeeded.gif", "Place holder.jpg", "Unbenannt.JPG", "UploadACopyrightFreeImage.svg", "UploadAnImage.gif", "UploadAnImage.svg", "UploadAnImageShort.svg", "CarersLogo.gif", "Diagram Needed.svg", "No male portrait.svg", "NoDVDcover copy.png", "Placeholder barnstar ribbon.png", "Project Trains no image.png", "Image-request.png", "Noimage.gif", } function i.IsPlaceholder(image) -- change underscores to spaces image = mw.ustring.gsub(image, "_", " "); assert(image ~= nil, 'mw.ustring.gsub(image, "_", " ") must not return nil') -- if image starts with [[ then remove that and anything after | if mw.ustring.sub(image,1,2) == "[[" then image = mw.ustring.sub(image,3); image = mw.ustring.gsub(image, "([^|]*)|.*", "%1"); assert(image ~= nil, 'mw.ustring.gsub(image, "([^|]*)|.*", "%1") must not return nil') end -- Trim spaces image = mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1'); assert(image ~= nil, "mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1') must not return nil") -- remove prefix if exists local allNames = mw.site.namespaces[6].aliases allNames[#allNames + 1] = mw.site.namespaces[6].name allNames[#allNames + 1] = mw.site.namespaces[6].canonicalName for i, name in ipairs(allNames) do if mw.ustring.lower(mw.ustring.sub(image, 1, mw.ustring.len(name) + 1)) == mw.ustring.lower(name .. ":") then image = mw.ustring.sub(image, mw.ustring.len(name) + 2); break end end -- Trim spaces image = mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1'); -- capitalise first letter image = mw.ustring.upper(mw.ustring.sub(image,1,1)) .. mw.ustring.sub(image,2); for i,j in pairs(placeholder_image) do if image == j then return true end end return false end function i.InfoboxImage(frame) local image = frame.args["image"]; if image == "" or image == nil then return ""; end if image == "&nbsp;" then return image; end if frame.args["suppressplaceholder"] ~= "no" then if i.IsPlaceholder(image) == true then return ""; end end if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "http:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "[http:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,7)) == "[[http:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "https:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,7)) == "[https:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,8)) == "[[https:" then return ""; end if mw.ustring.sub(image,1,2) == "[[" then -- search for thumbnail images and add to tracking cat if found local cat = ""; if mw.title.getCurrentTitle().namespace == 0 and (mw.ustring.find(image, "|%s*thumb%s*[|%]]") or mw.ustring.find(image, "|%s*thumbnail%s*[|%]]")) then cat = "[[Category:Pages using infoboxes with thumbnail images]]"; end return image .. cat; elseif mw.ustring.sub(image,1,2) == "{{" and mw.ustring.sub(image,1,3) ~= "{{{" then return image; elseif mw.ustring.sub(image,1,1) == "<" then return image; elseif mw.ustring.sub(image,1,5) == mw.ustring.char(127).."UNIQ" then -- Found strip marker at begining, so pass don't process at all return image; elseif mw.ustring.sub(image,4,9) == "`UNIQ-" then -- Found strip marker at begining, so pass don't process at all return image; else local result = ""; local page = frame.args["page"]; local size = frame.args["size"]; local maxsize = frame.args["maxsize"]; local sizedefault = frame.args["sizedefault"]; local alt = frame.args["alt"]; local link = frame.args["link"]; local title = frame.args["title"]; local border = frame.args["border"]; local upright = frame.args["upright"] or ""; local thumbtime = frame.args["thumbtime"] or ""; local center = frame.args["center"]; local class = frame.args["class"]; -- remove prefix if exists local allNames = mw.site.namespaces[6].aliases allNames[#allNames + 1] = mw.site.namespaces[6].name allNames[#allNames + 1] = mw.site.namespaces[6].canonicalName for i, name in ipairs(allNames) do if mw.ustring.lower(mw.ustring.sub(image, 1, mw.ustring.len(name) + 1)) == mw.ustring.lower(name .. ":") then image = mw.ustring.sub(image, mw.ustring.len(name) + 2); break end end if maxsize ~= "" and maxsize ~= nil then -- if no sizedefault then set to maxsize if sizedefault == "" or sizedefault == nil then sizedefault = maxsize end -- check to see if size bigger than maxsize if size ~= "" and size ~= nil then local sizenumber = tonumber(mw.ustring.match(size,"%d*")) or 0; local maxsizenumber = tonumber(mw.ustring.match(maxsize,"%d*")) or 0; if sizenumber>maxsizenumber and maxsizenumber>0 then size = maxsize; end end end -- add px to size if just a number if (tonumber(size) or 0) > 0 then size = size .. "px"; end -- add px to sizedefault if just a number if (tonumber(sizedefault) or 0) > 0 then sizedefault = sizedefault .. "px"; end result = "[[File:" .. image; if page ~= "" and page ~= nil then result = result .. "|page=" .. page; end if size ~= "" and size ~= nil then result = result .. "|" .. size; elseif sizedefault ~= "" and sizedefault ~= nil then result = result .. "|" .. sizedefault; else result = result .. "|frameless"; end if center == "yes" then result = result .. "|center" end if alt ~= "" and alt ~= nil then result = result .. "|alt=" .. alt; end if link ~= "" and link ~= nil then result = result .. "|link=" .. link; end if border == "yes" then result = result .. "|border"; end if upright == "yes" then result = result .. "|upright"; elseif upright ~= "" then result = result .. "|upright=" .. upright; end if thumbtime ~= "" then result = result .. "|thumbtime=" .. thumbtime; end if class ~= nil and class ~= "" then result = result .. "|class=" .. class; end -- if alt value is a keyword then do not use as a description if alt == "thumbnail" or alt == "thumb" or alt == "frameless" or alt == "left" or alt == "center" or alt == "right" or alt == "upright" or alt == "border" or mw.ustring.match(alt or "", '^[0-9]*px$', 1) ~= nil then alt = nil; end if title ~= "" and title ~= nil then -- does title param contain any templatestyles? If yes then set to blank. if mw.ustring.match(frame:preprocess(title), 'UNIQ%-%-templatestyles', 1) ~= nil then title = nil; end end if title ~= "" and title ~= nil then result = result .. "|" .. title; end result = result .. "]]"; return result; end end return i; 0ee5fe75ba239fc5c9cedc81ca11bdc0be068542 25 24 2023-10-05T10:27:47Z PeachFullzZ 2 ป้องกัน "[[มอดูล:InfoboxImage]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- Inputs: -- image - Can either be a bare filename (with or without the File:/Image: prefix) or a fully formatted image link -- page - page to display for multipage images (DjVu) -- size - size to display the image -- maxsize - maximum size for image -- sizedefault - default size to display the image if size param is blank -- alt - alt text for image -- title - title text for image -- border - set to yes if border -- center - set to yes, if the image has to be centered -- upright - upright image param -- suppressplaceholder - if yes then checks to see if image is a placeholder and suppresses it -- link - page to visit when clicking on image -- class - HTML classes to add to the image -- Outputs: -- Formatted image. -- More details available at the "Module:InfoboxImage/doc" page local i = {}; local placeholder_image = { "Blue - Replace this image female.svg", "Blue - Replace this image male.svg", "Female no free image yet.png", "Flag of None (square).svg", "Flag of None.svg", "Flag of.svg", "Green - Replace this image female.svg", "Green - Replace this image male.svg", "Image is needed female.svg", "Image is needed male.svg", "Location map of None.svg", "Male no free image yet.png", "Missing flag.png", "No flag.svg", "No free portrait.svg", "No portrait (female).svg", "No portrait (male).svg", "Red - Replace this image female.svg", "Red - Replace this image male.svg", "Replace this image female (blue).svg", "Replace this image female.svg", "Replace this image male (blue).svg", "Replace this image male.svg", "Silver - Replace this image female.svg", "Silver - Replace this image male.svg", "Replace this image.svg", "Cricket no pic.png", "CarersLogo.gif", "Diagram Needed.svg", "Example.jpg", "Image placeholder.png", "No male portrait.svg", "Nocover-upload.png", "NoDVDcover copy.png", "Noribbon.svg", "No portrait-BFD-test.svg", "Placeholder barnstar ribbon.png", "Project Trains no image.png", "Image-request.png", "Sin bandera.svg", "Sin escudo.svg", "Replace this image - temple.png", "Replace this image butterfly.png", "Replace this image.svg", "Replace this image1.svg", "Resolution angle.png", "Image-No portrait-text-BFD-test.svg", "Insert image here.svg", "No image available.png", "NO IMAGE YET square.png", "NO IMAGE YET.png", "No Photo Available.svg", "No Screenshot.svg", "No-image-available.jpg", "Null.png", "PictureNeeded.gif", "Place holder.jpg", "Unbenannt.JPG", "UploadACopyrightFreeImage.svg", "UploadAnImage.gif", "UploadAnImage.svg", "UploadAnImageShort.svg", "CarersLogo.gif", "Diagram Needed.svg", "No male portrait.svg", "NoDVDcover copy.png", "Placeholder barnstar ribbon.png", "Project Trains no image.png", "Image-request.png", "Noimage.gif", } function i.IsPlaceholder(image) -- change underscores to spaces image = mw.ustring.gsub(image, "_", " "); assert(image ~= nil, 'mw.ustring.gsub(image, "_", " ") must not return nil') -- if image starts with [[ then remove that and anything after | if mw.ustring.sub(image,1,2) == "[[" then image = mw.ustring.sub(image,3); image = mw.ustring.gsub(image, "([^|]*)|.*", "%1"); assert(image ~= nil, 'mw.ustring.gsub(image, "([^|]*)|.*", "%1") must not return nil') end -- Trim spaces image = mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1'); assert(image ~= nil, "mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1') must not return nil") -- remove prefix if exists local allNames = mw.site.namespaces[6].aliases allNames[#allNames + 1] = mw.site.namespaces[6].name allNames[#allNames + 1] = mw.site.namespaces[6].canonicalName for i, name in ipairs(allNames) do if mw.ustring.lower(mw.ustring.sub(image, 1, mw.ustring.len(name) + 1)) == mw.ustring.lower(name .. ":") then image = mw.ustring.sub(image, mw.ustring.len(name) + 2); break end end -- Trim spaces image = mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1'); -- capitalise first letter image = mw.ustring.upper(mw.ustring.sub(image,1,1)) .. mw.ustring.sub(image,2); for i,j in pairs(placeholder_image) do if image == j then return true end end return false end function i.InfoboxImage(frame) local image = frame.args["image"]; if image == "" or image == nil then return ""; end if image == "&nbsp;" then return image; end if frame.args["suppressplaceholder"] ~= "no" then if i.IsPlaceholder(image) == true then return ""; end end if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "http:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "[http:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,7)) == "[[http:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "https:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,7)) == "[https:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,8)) == "[[https:" then return ""; end if mw.ustring.sub(image,1,2) == "[[" then -- search for thumbnail images and add to tracking cat if found local cat = ""; if mw.title.getCurrentTitle().namespace == 0 and (mw.ustring.find(image, "|%s*thumb%s*[|%]]") or mw.ustring.find(image, "|%s*thumbnail%s*[|%]]")) then cat = "[[Category:Pages using infoboxes with thumbnail images]]"; end return image .. cat; elseif mw.ustring.sub(image,1,2) == "{{" and mw.ustring.sub(image,1,3) ~= "{{{" then return image; elseif mw.ustring.sub(image,1,1) == "<" then return image; elseif mw.ustring.sub(image,1,5) == mw.ustring.char(127).."UNIQ" then -- Found strip marker at begining, so pass don't process at all return image; elseif mw.ustring.sub(image,4,9) == "`UNIQ-" then -- Found strip marker at begining, so pass don't process at all return image; else local result = ""; local page = frame.args["page"]; local size = frame.args["size"]; local maxsize = frame.args["maxsize"]; local sizedefault = frame.args["sizedefault"]; local alt = frame.args["alt"]; local link = frame.args["link"]; local title = frame.args["title"]; local border = frame.args["border"]; local upright = frame.args["upright"] or ""; local thumbtime = frame.args["thumbtime"] or ""; local center = frame.args["center"]; local class = frame.args["class"]; -- remove prefix if exists local allNames = mw.site.namespaces[6].aliases allNames[#allNames + 1] = mw.site.namespaces[6].name allNames[#allNames + 1] = mw.site.namespaces[6].canonicalName for i, name in ipairs(allNames) do if mw.ustring.lower(mw.ustring.sub(image, 1, mw.ustring.len(name) + 1)) == mw.ustring.lower(name .. ":") then image = mw.ustring.sub(image, mw.ustring.len(name) + 2); break end end if maxsize ~= "" and maxsize ~= nil then -- if no sizedefault then set to maxsize if sizedefault == "" or sizedefault == nil then sizedefault = maxsize end -- check to see if size bigger than maxsize if size ~= "" and size ~= nil then local sizenumber = tonumber(mw.ustring.match(size,"%d*")) or 0; local maxsizenumber = tonumber(mw.ustring.match(maxsize,"%d*")) or 0; if sizenumber>maxsizenumber and maxsizenumber>0 then size = maxsize; end end end -- add px to size if just a number if (tonumber(size) or 0) > 0 then size = size .. "px"; end -- add px to sizedefault if just a number if (tonumber(sizedefault) or 0) > 0 then sizedefault = sizedefault .. "px"; end result = "[[File:" .. image; if page ~= "" and page ~= nil then result = result .. "|page=" .. page; end if size ~= "" and size ~= nil then result = result .. "|" .. size; elseif sizedefault ~= "" and sizedefault ~= nil then result = result .. "|" .. sizedefault; else result = result .. "|frameless"; end if center == "yes" then result = result .. "|center" end if alt ~= "" and alt ~= nil then result = result .. "|alt=" .. alt; end if link ~= "" and link ~= nil then result = result .. "|link=" .. link; end if border == "yes" then result = result .. "|border"; end if upright == "yes" then result = result .. "|upright"; elseif upright ~= "" then result = result .. "|upright=" .. upright; end if thumbtime ~= "" then result = result .. "|thumbtime=" .. thumbtime; end if class ~= nil and class ~= "" then result = result .. "|class=" .. class; end -- if alt value is a keyword then do not use as a description if alt == "thumbnail" or alt == "thumb" or alt == "frameless" or alt == "left" or alt == "center" or alt == "right" or alt == "upright" or alt == "border" or mw.ustring.match(alt or "", '^[0-9]*px$', 1) ~= nil then alt = nil; end if title ~= "" and title ~= nil then -- does title param contain any templatestyles? If yes then set to blank. if mw.ustring.match(frame:preprocess(title), 'UNIQ%-%-templatestyles', 1) ~= nil then title = nil; end end if title ~= "" and title ~= nil then result = result .. "|" .. title; end result = result .. "]]"; return result; end end return i; 0ee5fe75ba239fc5c9cedc81ca11bdc0be068542 แม่แบบ:กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office 10 16 26 2023-10-05T10:31:02Z PeachFullzZ 2 สร้างหน้าด้วย "{{#if:{{{speaker|}}}{{{state_legislature|}}}{{{state_assembly|}}}{{{speaker_office|}}}{{{state_delegate|}}}{{{state_house|}}}{{{prior_term|}}}{{{nominee|}}}{{{candidate|}}}{{{termstart|}}}{{{election_date|}}}{{{majority_leader|}}}{{{minority_floor_leader|}}}{{{minority_leader|}}}{{{majority_floor_leader|}}}{{{jr/sr|}}}{{{succeeding|}}}{{{assuming|}}}{{{state|}}}{{{jr/sr and state|}}}{{{state_senate|}}}{{{district|}}}{{{ambassador_from|}}}{{{minister..." wikitext text/x-wiki {{#if:{{{speaker|}}}{{{state_legislature|}}}{{{state_assembly|}}}{{{speaker_office|}}}{{{state_delegate|}}}{{{state_house|}}}{{{prior_term|}}}{{{nominee|}}}{{{candidate|}}}{{{termstart|}}}{{{election_date|}}}{{{majority_leader|}}}{{{minority_floor_leader|}}}{{{minority_leader|}}}{{{majority_floor_leader|}}}{{{jr/sr|}}}{{{succeeding|}}}{{{assuming|}}}{{{state|}}}{{{jr/sr and state|}}}{{{state_senate|}}}{{{district|}}}{{{ambassador_from|}}}{{{minister_from|}}}{{{order|}}}{{{office|}}}{{{title|}}}{{{country|}}}{{{constituency_AM|}}}{{{constituency_MP|}}}{{{parliament|}}}{{{assembly|}}}{{{constituency_|}}}{{{riding|}}}{{{term|}}}{{{termend|}}}{{{alongside|}}}{{{co-leader|}}} |{{#invoke:infobox|infoboxTemplate|child=yes|decat=yes | headerstyle = background:{{{color|lavender}}};line-height:normal;padding:0.2em; | datastyle = border-bottom:none <!--------Speaker of the House---------> | header1 = {{#if:{{{speaker|}}}| {{{speaker}}} {{#if:{{{state_legislature|}}} |[[Speaker of the {{{state_legislature}}} Legislature]] |{{#if:{{{state_assembly|}}} |[[Speaker of the {{{state_assembly|}}} {{#ifeq:{{{state_assembly|}}}|Nevada||{{#ifeq:{{{state_assembly|}}}|New Jersey|General|State}}}} Assembly]] |{{#if:{{{speaker_office|}}}|{{{speaker_office}}}|[[Speaker of the {{#if:{{{state_delegate|}}} |{{{state_delegate}}}|{{#if:{{{state_house|}}} |{{{state_house}}}|United States}}}} House of {{#if:{{{state_delegate|}}}|Delegates|Representatives}}|ประธานสภา{{#if:{{{state_delegate|}}}|Delegates|ผู้แทนราษฎร}}{{#if:{{{state_delegate|}}} |{{{state_delegate}}}|{{#if:{{{state_house|}}} |{{{state_house}}}|สหรัฐ}}}}]]}} }} }}{{#if:{{{prior_term|}}}| <br />{{{prior_term}}}}} }} <!--------ตำแหน่ง---------> | header2 = {{#if:{{{nominee|}}}{{{candidate|}}}| {{#if:{{{party_election|}}}{{{party|}}} |ผู้ได้รับเสนอชื่อเป็น<br>{{#if:{{{nominee|}}}|{{{nominee}}}|{{{candidate}}}}}ของ{{#if:{{{party_election|}}}|{{{party_election}}}|{{{party}}}}} |ผู้ได้รับเสนอชื่อเป็น<br>{{#if:{{{nominee|}}}|{{{nominee}}}|{{{candidate}}}}} }} }} | data3 = {{#if:{{{nominee|}}}{{{candidate|}}}| {{#if:{{{termstart|}}}{{{election_date|}}} | {{nowrap|'''วันเลือกตั้ง'''}}<br />{{#if:{{{election_date|}}}|{{{election_date}}}|{{{termstart}}}}} }} }} | header4 = {{#if:{{{majority_leader|}}}{{{minority_floor_leader|}}}{{{minority_leader|}}}{{{majority_floor_leader|}}}|| {{#if:{{{jr/sr|}}}|[[วุฒิสภาสหรัฐ|<!--Changed code to eliminate "Junior/Senior" distinction for U.S. Senators per [[Template talk:Infobox Officeholder/Archive 9#Senior/Junior U.S. Senators]]{{{jr/sr}}}-->{{#if:{{{succeeding|}}}{{{assuming|}}}|ผู้ที่ได้รับเลือกตั้งเป็น}}สมาชิกวุฒิสภาสหรัฐ]]<br />จาก{{{state}}} }} }} | header5 = {{#if:{{{majority_leader|}}}{{{minority_floor_leader|}}}{{{minority_leader|}}}{{{majority_floor_leader|}}}|| {{{jr/sr and state|}}} }} | header6 = {{#if:{{{majority_leader|}}}{{{minority_floor_leader|}}}{{{minority_leader|}}}{{{majority_floor_leader|}}}|| {{#if:{{{state_senate|}}}|{{#if:{{{succeeding|}}}{{{assuming|}}}|ผู้ที่ได้รับเลือกตั้งเป็น}}สมาชิก<span style="display: inline-block;">[[วุฒิสภา{{{state_senate}}}]]</span><br />จากเขต{{{district}}} {{#if:{{{prior_term|}}}| <br />{{{prior_term}}}}} }} }} | header7 = {{#if:{{{majority_leader|}}}{{{minority_floor_leader|}}}{{{minority_leader|}}}{{{majority_floor_leader|}}}|| {{#if:{{{state_legislature|}}}|{{#if:{{{succeeding|}}}{{{assuming|}}}|ผู้ที่ได้รับเลือกตั้งเป็น}}สมาชิก<span style="display: inline-block;">[[สภาผู้แทนราษฎร{{{state_legislature}}}]]</span><br />จากเขต{{{district}}} }} }} | header8 = {{#if:{{{ambassador_from|}}}{{{minister_from|}}}|| {{#if:{{{order|}}} |{{#if:{{{office|}}}|&#32;[[{{{office}}}]]}}{{#if:{{{state|}}} |&#32;[[{{{state}}}]]}}{{#if:{{{title|}}} |&#32;{{{title}}}}} {{{order}}} |{{{office|}}} }} }} | header9 = {{#if:{{{ambassador_from|}}}{{{minister_from|}}}|| {{#if:{{{order|}}} ||{{{title|}}} }} }} <!--------Ambassador---------> | header10 = {{#if:{{both|{{{ambassador_from|}}}{{{minister_from|}}}|{{{country|}}}}} |{{#if:{{{order|}}}|{{{order}}}}} {{#if:{{{minister_from|}}} |[[{{{minister_from}}} Ambassador to {{CountryPrefixThe|{{{country}}}}}|{{{minister_from}}} Minister to <span class="nowrap">{{CountryPrefixThe|{{{country}}}}}</span>]] |[[{{{ambassador_from}}} Ambassador to {{CountryPrefixThe|{{{country}}}}}|{{{ambassador_from}}} Ambassador to <span class="nowrap">{{CountryPrefixThe|{{{country}}}}}</span>]] }} [[Category:Pages using infobox officeholder with ambassador from or minister from]] }} <!--------MP---------> | header11 = {{#if:{{{constituency_AM|}}}{{{constituency_MP|}}}| {{#switch:{{{parliament|}}} |Australian|ออสเตรเลีย = สมาชิก<span style="display: inline-block;">[[สภาผู้แทนราษฎรออสเตรเลีย]]</span> |European|ยุโรป = [[สมาชิกรัฐสภายุโรป|สมาชิก]][[รัฐสภายุโรป]] |Scottish|สกอตแลนด์ = [[สมาชิกรัฐสภาสกอตแลนด์|สมาชิก]][[รัฐสภาสกอตแลนด์]] |Sri Lanka|Sri Lankan = [[Member of Parliament (Sri Lanka)|Member of Parliament]] |United Kingdom|UK = [[Member of Parliament (United Kingdom)|Member of Parliament]] |#default = {{#if:{{{constituency_AM|}}}|{{#if:{{{assembly|}}}|Member of the <span style="display: inline-block;">[[{{{assembly}}} Assembly]]</span>|Assembly Member}}|Member of {{#if:{{{parliament|}}}|the <span style="display: inline-block;">[[{{{parliament}}} Parliament]]</span>|Parliament}}}}}}<br />for {{#ifeq:{{Title disambig text|{{{constituency_MP|}}}}}|UK Parliament constituency |{{{constituency_MP|}}} |{{#if:{{#switch:{{{parliament|}}} |United Kingdom|UK| = {{Linkless exists|{{delink|{{{constituency_MP|}}}}} (UK Parliament constituency)}} }} |{{#if:{{Constlk|{{delink|{{{constituency_MP|}}}}}}} |{{Constlk|{{delink|{{{constituency_MP|}}}}}}} |{{{constituency_{{#if:{{{constituency_AM|}}}|AM|MP}}}}}}} |{{{constituency_{{#if:{{{constituency_AM|}}}|AM|MP}}}}}}} }}{{#if:{{{prior_term|}}}| <div style="font-weight:normal;">{{{prior_term}}}</div>}} }} | header12 = {{#if:{{{riding|}}}|{{#if:{{{constituency_AM|}}}|{{#if:{{{assembly|}}}|Member of the <span style="display: inline-block;">[[{{{assembly}}} Assembly]]</span>|Assembly Member}}| {{#switch:{{{parliament|}}} |Canadian = [[Member of Parliament (Canada)|Member of Parliament]] |#default = Member of {{#if:{{{parliament|}}}|the <span style="display: inline-block;">[[{{{parliament}}} Parliament]]</span>|Parliament}}}}}}<br />for {{{riding}}} }} <!--------Majority Leader (State Senate)---------> | header13 = {{#if:{{{majority_leader|}}}|{{{majority_leader}}} {{#if:{{{state_senate|}}}|[[Majority Leader of the {{{state_senate}}} Senate]]|[[United States Senate Majority Leader]]}} }} <!--------Majority Floor Leader (State Senate)---------> | header14 = {{#if:{{{majority_floor_leader|}}}|{{{majority_floor_leader}}} [[Majority Floor Leader of the {{{state_senate}}} Senate]] }} <!--------Minority Leader (State Senate)---------> | header15 = {{#if:{{{minority_leader|}}}|{{{minority_leader}}} [[Minority Leader of the {{{state_senate}}} Senate]] }} <!--------Minority Floor Leader (State Senate)---------> | header16 = {{#if:{{{minority_floor_leader|}}}|{{{minority_floor_leader}}} [[Minority Floor Leader of the {{{state_senate}}} Senate]] }} <!--------Congressman---------> | header17 = {{#if:{{{state_legislature|}}}{{{state_senate|}}}{{{jr/sr|}}}{{{jr/sr and state|}}}|| {{#if:{{#if:{{{state|}}}|{{{constituency|}}}}}{{{district|}}}{{{state_house|}}}|{{#if:{{{state_assembly|}}} |Member{{#if:{{{succeeding|}}}{{{assuming|}}}|-elect}} of the <span style="display: inline-block;">[[{{{state_assembly|}}} {{#ifeq:{{{state_assembly|}}}|Nevada||{{#ifeq:{{{state_assembly|}}}|New Jersey|General|State}}}} Assembly]]</span><br />from the |Member{{#if:{{{succeeding|}}}{{{assuming|}}}|-elect}} of the <span style="display: inline-block;">[[{{#if:{{{state_house|}}} |{{{state_house}}}|{{#if:{{{state_delegate|}}}|{{{state_delegate}}}|United States }}}} {{#if:{{{state_delegate|}}}|House of Delegates|House of Representatives}}|{{#if:{{{state_house|}}} |{{{state_house}}}|{{#if:{{{state_delegate|}}}|{{{state_delegate}}}|U.S.}}}}&#32;{{#if:{{{state_delegate|}}}|House&#32;of&#32;Delegates|{{#if:{{{state_house|}}}| }}House&#32;of&#32;Representatives}}]]</span>{{#if:{{{district|}}}{{{state|}}}{{{state_delegate|}}}{{{state_house|}}}|<br />from {{#if:{{{state_delegate|}}}|the |{{#if:{{{state_house|}}}|{{#if:{{{district|}}}|the|{{{state|}}}}}|{{{state|}}}{{#if:{{{district|}}}|'s}}}}}} }}}} {{#if:{{{district|}}}|{{{district}}} district|{{#if:{{{state_house|}}}|{{{constituency|}}}}}}}{{#if:{{{prior_term|}}}| <br />{{{prior_term}}}}} }} }} <!--------Convocation---------> | header18 = {{#if:{{{convocation|}}}|{{{convocation}}}}} <!--------Term---------> | data19 = {{#if:{{{termend|}}}{{{succeeding|}}}{{{assuming|}}}| {{#if:{{{status|}}} | <div style="width:100%; margin:0; background-color: {{{color|lavender}}}">'''{{{status}}}'''</div>|}}| }} | data20 = {{#if:{{{nominee|}}}{{{candidate|}}}|| {{#if:{{{succeeding|}}}{{{assuming|}}} | <span class="nowrap">'''ว่าที่ตำแหน่ง'''</span><br />{{{termstart}}}{{#if:{{{term|}}}{{{termend|}}}|[[Category:Pages using infobox officeholder with succeeding and term or termend]]}} | {{#if: {{{term|}}} | <span class="nowrap">'''{{{termlabel|ดำรงตำแหน่ง}}}'''</span><br />{{{term}}} }} }} }} | data21 = {{#if:{{{nominee|}}}{{{candidate|}}}|| {{#if:{{{succeeding|}}}{{{assuming|}}} | |{{#if:{{{termstart|}}} | {{#if:{{{termend|}}} |<!--then: term has start and end:--><span class="nowrap">'''{{{termlabel|ดำรงตำแหน่ง}}}'''</span><br />{{en dash range|{{{termstart}}}|{{{termend}}}}}{{#if:{{{alongside|}}}{{{co-leader|}}}|<div style="line-height:normal; padding-top:0.2em; padding-bottom:0.1em">{{#if:{{{alongside|}}}|ดำรงตำแหน่ง|เป็นผู้นำ}}ร่วมกับ{{#if:{{{alongside|}}}|{{{alongside}}}|{{{co-leader}}}}}</div>}} |{{#if:{{{status|}}}|<div style="width:100%; margin:0; background-color: {{{color|lavender}}}">'''{{{status}}}'''</div>|<!--else: term is ongoing--><div style="width:100%; margin:0; background-color: {{{color|lavender}}}">'''[[การดำรงตำแหน่ง|อยู่ในวาระ]]'''</div>}} }} }} }} }} | data22 = {{#if:{{{nominee|}}}{{{candidate|}}}|| {{#if:{{{succeeding|}}}{{{assuming|}}} | |{{#if:{{{termstart|}}} |{{#if:{{{termend|}}} |<!--then nothing else; term has ended--> |<!--else term is ongoing:--><span class="nowrap">'''{{#if:{{{termlabel|}}}|{{str rep|1={{{termlabel}}}|2=ดำรงตำแหน่ง|3=เริ่มดำรงตำแหน่ง}}|เริ่มดำรงตำแหน่ง}}'''</span>&#32;<br />{{{termstart}}}{{#if:{{{alongside|}}}{{{co-leader|}}}|<div style="line-height:normal; padding-top:0.2em; padding-bottom:0.1em">{{#if:{{{alongside|}}}|ดำรงตำแหน่ง|เป็นผู้นำ}}ร่วมกับ{{#if:{{{alongside|}}}|{{{alongside}}}|{{{co-leader}}}}}</div>}} }} }} }} }} }} }}<!-- end infobox1 / start infobox2 -->{{#if:{{{monarch|}}}{{{president|}}}{{{governor-general|}}}{{{governor_general|}}}{{{primeminister|}}}{{{chancellor|}}}{{{minister|}}}{{{taoiseach|}}}{{{firstminister|}}}{{{chiefminister|}}}{{{premier|}}}{{{governor|}}}{{{lieutenant_governor|}}}{{{vicepresident|}}}{{{vicegovernor|}}}{{{viceprimeminister|}}}{{{vicepremier|}}}{{{deputy|}}}{{{leader|}}}{{{lieutenant|}}}{{{nominator|}}}{{{appointer|}}}{{{opponent|}}}{{{incumbent|}}}{{{succeeding|}}}{{{assuming|}}}{{{preceding|}}}{{{predecessor|}}}{{{preceded|}}}{{{successor|}}}{{{succeeded|}}}{{{parliamentarygroup|}}}{{{constituency|}}}{{{majority|}}}{{{suboffice|}}}{{{1namedata|}}}{{{2namedata|}}}{{{3namedata|}}}{{{4namedata|}}}{{{5namedata|}}}{{{runningmate|}}}| {{#invoke:infobox|infoboxTemplate|child=yes | labelstyle = text-align:left | label1 = {{nowrap|เสนอชื่อโดย}} | data1 = {{{nominator|}}} | label2 = {{nowrap|แต่งตั้งโดย}} | data2 = {{{appointer|}}} <!--------President, Prime Minister, Governor---------> | label3 = กษัตริย์ | data3 = {{{monarch|}}} | label4 = ประธานาธิบดี | data4 = {{{president|}}} | label5 = {{nowrap|ผู้สำเร็จราชการแทนพระองค์}} | data5 = {{#if:{{{governor_general|}}}|{{{governor_general}}}|{{{governor-general|}}}}} | label6 = {{nowrap|นายกรัฐมนตรี}} | data6 = {{{primeminister|}}} | label7 = หัวหน้ารัฐบาล | data7 = {{{chancellor|}}} | label8 = รัฐมนตรี | data8 = {{{minister|}}} | label9 = ทีเชิฆ | data9 = {{{taoiseach|}}} | label10 = {{nowrap|มุขมนตรี}} | data10 = {{{firstminister|}}} | label11 = {{nowrap|หัวหน้ารัฐบาล}} | data11 = {{{chiefminister|}}} | label12 = หัวหน้ารัฐบาล | data12 = {{{premier|}}} | label13 = ผู้ว่าราชการ | data13 = {{{governor|}}} | label14 = รองผู้ว่าราชการ | data14 = {{{lieutenant_governor|}}} <!--------Vice president/s, Vice Prime Minister/s, Deputy/ies, Lieutenant/s---------> | label15 = <span class="nowrap">{{#if:{{{office|}}}|{{#ifeq:{{isValidPageName|รอง{{{office}}}}}|valid|[[รอง{{{office}}}|รองประธานาธิบดี]]|รองประธานาธิบดี}}|รองประธานาธิบดี}}</span> | data15 = {{{vicepresident|}}} | label16 = <span class="nowrap">{{#if:{{{office|}}}|{{#ifeq:{{isValidPageName|รอง{{{office}}}}}|valid|[[รอง{{{office}}}|รองผู้ว่าการ]]|รองผู้ว่าการ}}|รองผู้ว่าการ}}</span> | data16 = {{{vicegovernor|}}} | label17 = <span class="nowrap">{{#if:{{{office|}}}|[[รอง{{{office}}}|รองนายกรัฐมนตรี]]|รอง[[นายกรัฐมนตรี]]}}</span> | data17 = {{{viceprimeminister|}}} | label18 = <span class="nowrap">{{#if:{{{office|}}}|{{#ifeq:{{isValidPageName|รอง{{{office}}}}}|valid|[[รอง{{{office}}}|รองหัวหน้ารัฐบาล]]|รองหัวหน้ารัฐบาล}}|รองหัวหน้ารัฐบาล}}</span> | data18 = {{{vicepremier|}}} | label19 = {{#if:{{{office|}}}|{{#ifeq:{{isValidPageName|รอง{{{office}}}}}|valid|[[รอง{{{office}}}|รอง]]|รอง}}|รอง}} | data19 = {{{deputy|}}} | label20 = รัฐมนตรีช่วย | data20 = {{{deputyminister|}}} | label21 = รัฐมนตรีว่าการ | data21 = {{{headminister|}}} | label22 = ผู้นำ | data22 = {{{leader|}}} | label23 = {{#if:{{{office|}}}|[[รักษาการแทน{{{office}}}|รักษาการแทน]]|รักษาการแทน}} | data23 = {{{lieutenant|}}} | label24 = {{nowrap|{{{subterm|}}}}} | data24 = {{{suboffice|}}} <!--------Blank fields---------> | label25 = {{{1blankname|}}} | data25 = {{{1namedata|}}} | label26 = {{{2blankname|}}} | data26 = {{{2namedata|}}} | label27 = {{{3blankname|}}} | data27 = {{{3namedata|}}} | label28 = {{{4blankname|}}} | data28 = {{{4namedata|}}} | label29 = {{{5blankname|}}} | data29 = {{{5namedata|}}} <!--------Predecessor/successor---------> | label30 = <span class="nowrap">ผู้ร่วมหาเสียง</span> | data30 = {{{runningmate|}}} | label31 = คู่แข่ง | data31 = {{{opponent|}}} | label32 = อยู่ในวาระ | data32 = {{{incumbent|}}} | label33 = {{#if:{{{succeeding|}}}|รับช่วงจาก|ส่งต่อให้}} | data33 = {{#if:{{{succeeding|}}}|{{{succeeding|}}}|{{{preceding|}}}}} | label34 = <span class="nowrap">ก่อนหน้า</span> | data34 = {{#if:{{{succeeding|}}}||{{#if:{{{predecessor|}}}|{{{predecessor}}}|{{{preceded|}}}}}}} | label35 = <span class="nowrap">ถัดไป</span> | data35 = {{#if:{{{succeeding|}}}||{{#switch:{{#if:{{{successor|}}}|{{{successor}}}|{{{succeeded|}}}}} | อยู่ในตำแหน่ง | '''อยู่ในตำแหน่ง''' | ''อยู่ในตำแหน่ง'' | [[การดำรงตำแหน่ง|อยู่ในตำแหน่ง]] | อยู่ในตำแหน่ง | '''อยู่ในตำแหน่ง''' | ''อยู่ในตำแหน่ง'' | [[การดำรงตำแหน่ง|อยู่ในตำแหน่ง]] = | #default = {{#if:{{{successor|}}}|{{{successor}}}|{{{succeeded|}}}}} }}}} <!--------Constituency/Majority---------> | label36 = [[กลุ่มรัฐสภา]] | data36 = {{{parliamentarygroup|}}} | label37 = เขตเลือกตั้ง | data37 = {{{constituency|}}} | label38 = คะแนนเสียง | data38 = {{{majority|}}} }} }}<noinclude> {{คู่มือการใช้งาน}} </noinclude> 1ad8321abb565d488217abaac5ced8c6aa2fddcb 39 26 2023-10-05T11:12:26Z PeachFullzZ 2 wikitext text/x-wiki {{#if:{{{speaker|}}}{{{state_legislature|}}}{{{state_assembly|}}}{{{speaker_office|}}}{{{state_delegate|}}}{{{state_house|}}}{{{prior_term|}}}{{{nominee|}}}{{{candidate|}}}{{{termstart|}}}{{{election_date|}}}{{{majority_leader|}}}{{{minority_floor_leader|}}}{{{minority_leader|}}}{{{majority_floor_leader|}}}{{{jr/sr|}}}{{{succeeding|}}}{{{assuming|}}}{{{state|}}}{{{jr/sr and state|}}}{{{state_senate|}}}{{{district|}}}{{{ambassador_from|}}}{{{minister_from|}}}{{{order|}}}{{{office|}}}{{{title|}}}{{{country|}}}{{{constituency_AM|}}}{{{constituency_MP|}}}{{{parliament|}}}{{{assembly|}}}{{{constituency_|}}}{{{riding|}}}{{{term|}}}{{{termend|}}}{{{alongside|}}}{{{co-leader|}}} |{{#invoke:infobox|infoboxTemplate|child=yes|decat=yes | headerstyle = background:{{{color|lavender}}};line-height:normal;padding:0.2em; | datastyle = border-bottom:none <!--------Speaker of the House---------> | header1 = {{#if:{{{speaker|}}}| {{{speaker}}} {{#if:{{{state_legislature|}}} |[[Speaker of the {{{state_legislature}}} Legislature]] |{{#if:{{{state_assembly|}}} |[[Speaker of the {{{state_assembly|}}} {{#ifeq:{{{state_assembly|}}}|Nevada||{{#ifeq:{{{state_assembly|}}}|New Jersey|General|State}}}} Assembly]] |{{#if:{{{speaker_office|}}}|{{{speaker_office}}}|[[Speaker of the {{#if:{{{state_delegate|}}} |{{{state_delegate}}}|{{#if:{{{state_house|}}} |{{{state_house}}}|United States}}}} House of {{#if:{{{state_delegate|}}}|Delegates|Representatives}}|ประธานสภา{{#if:{{{state_delegate|}}}|Delegates|ผู้แทนราษฎร}}{{#if:{{{state_delegate|}}} |{{{state_delegate}}}|{{#if:{{{state_house|}}} |{{{state_house}}}|สหรัฐ}}}}]]}} }} }}{{#if:{{{prior_term|}}}| <br />{{{prior_term}}}}} }} <!--------ตำแหน่ง---------> | header2 = {{#if:{{{nominee|}}}{{{candidate|}}}| {{#if:{{{party_election|}}}{{{party|}}} |ผู้ได้รับเสนอชื่อเป็น<br>{{#if:{{{nominee|}}}|{{{nominee}}}|{{{candidate}}}}}ของ{{#if:{{{party_election|}}}|{{{party_election}}}|{{{party}}}}} |ผู้ได้รับเสนอชื่อเป็น<br>{{#if:{{{nominee|}}}|{{{nominee}}}|{{{candidate}}}}} }} }} | data3 = {{#if:{{{nominee|}}}{{{candidate|}}}| {{#if:{{{termstart|}}}{{{election_date|}}} | {{nowrap|'''วันเลือกตั้ง'''}}<br />{{#if:{{{election_date|}}}|{{{election_date}}}|{{{termstart}}}}} }} }} | header4 = {{#if:{{{majority_leader|}}}{{{minority_floor_leader|}}}{{{minority_leader|}}}{{{majority_floor_leader|}}}|| {{#if:{{{jr/sr|}}}|[[วุฒิสภาสหรัฐ|<!--Changed code to eliminate "Junior/Senior" distinction for U.S. Senators per [[Template talk:Infobox Officeholder/Archive 9#Senior/Junior U.S. Senators]]{{{jr/sr}}}-->{{#if:{{{succeeding|}}}{{{assuming|}}}|ผู้ที่ได้รับเลือกตั้งเป็น}}สมาชิกวุฒิสภาสหรัฐ]]<br />จาก{{{state}}} }} }} | header5 = {{#if:{{{majority_leader|}}}{{{minority_floor_leader|}}}{{{minority_leader|}}}{{{majority_floor_leader|}}}|| {{{jr/sr and state|}}} }} | header6 = {{#if:{{{majority_leader|}}}{{{minority_floor_leader|}}}{{{minority_leader|}}}{{{majority_floor_leader|}}}|| {{#if:{{{state_senate|}}}|{{#if:{{{succeeding|}}}{{{assuming|}}}|ผู้ที่ได้รับเลือกตั้งเป็น}}สมาชิก<span style="display: inline-block;">[[วุฒิสภา{{{state_senate}}}]]</span><br />จากเขต{{{district}}} {{#if:{{{prior_term|}}}| <br />{{{prior_term}}}}} }} }} | header7 = {{#if:{{{majority_leader|}}}{{{minority_floor_leader|}}}{{{minority_leader|}}}{{{majority_floor_leader|}}}|| {{#if:{{{state_legislature|}}}|{{#if:{{{succeeding|}}}{{{assuming|}}}|ผู้ที่ได้รับเลือกตั้งเป็น}}สมาชิก<span style="display: inline-block;">[[สภาผู้แทนราษฎร{{{state_legislature}}}]]</span><br />จากเขต{{{district}}} }} }} | header8 = {{#if:{{{ambassador_from|}}}{{{minister_from|}}}|| {{#if:{{{order|}}} |{{#if:{{{office|}}}|&#32;[[{{{office}}}]]}}{{#if:{{{state|}}} |&#32;[[{{{state}}}]]}}{{#if:{{{title|}}} |&#32;{{{title}}}}} {{{order}}} |{{{office|}}} }} }} | header9 = {{#if:{{{ambassador_from|}}}{{{minister_from|}}}|| {{#if:{{{order|}}} ||{{{title|}}} }} }} <!--------MP---------> | header11 = {{#if:{{{constituency_AM|}}}{{{constituency_MP|}}}| {{#switch:{{{parliament|}}} |Australian|ออสเตรเลีย = สมาชิก<span style="display: inline-block;">[[สภาผู้แทนราษฎรออสเตรเลีย]]</span> |European|ยุโรป = [[สมาชิกรัฐสภายุโรป|สมาชิก]][[รัฐสภายุโรป]] |Scottish|สกอตแลนด์ = [[สมาชิกรัฐสภาสกอตแลนด์|สมาชิก]][[รัฐสภาสกอตแลนด์]] |Sri Lanka|Sri Lankan = [[Member of Parliament (Sri Lanka)|Member of Parliament]] |United Kingdom|UK = [[Member of Parliament (United Kingdom)|Member of Parliament]] |#default = {{#if:{{{constituency_AM|}}}|{{#if:{{{assembly|}}}|Member of the <span style="display: inline-block;">[[{{{assembly}}} Assembly]]</span>|Assembly Member}}|Member of {{#if:{{{parliament|}}}|the <span style="display: inline-block;">[[{{{parliament}}} Parliament]]</span>|Parliament}}}}}}<br />for {{#ifeq:{{Title disambig text|{{{constituency_MP|}}}}}|UK Parliament constituency |{{{constituency_MP|}}} |{{#if:{{#switch:{{{parliament|}}} |United Kingdom|UK| = {{Linkless exists|{{delink|{{{constituency_MP|}}}}} (UK Parliament constituency)}} }} |{{#if:{{Constlk|{{delink|{{{constituency_MP|}}}}}}} |{{Constlk|{{delink|{{{constituency_MP|}}}}}}} |{{{constituency_{{#if:{{{constituency_AM|}}}|AM|MP}}}}}}} |{{{constituency_{{#if:{{{constituency_AM|}}}|AM|MP}}}}}}} }}{{#if:{{{prior_term|}}}| <div style="font-weight:normal;">{{{prior_term}}}</div>}} }} | header12 = {{#if:{{{riding|}}}|{{#if:{{{constituency_AM|}}}|{{#if:{{{assembly|}}}|Member of the <span style="display: inline-block;">[[{{{assembly}}} Assembly]]</span>|Assembly Member}}| {{#switch:{{{parliament|}}} |Canadian = [[Member of Parliament (Canada)|Member of Parliament]] |#default = Member of {{#if:{{{parliament|}}}|the <span style="display: inline-block;">[[{{{parliament}}} Parliament]]</span>|Parliament}}}}}}<br />for {{{riding}}} }} <!--------Majority Leader (State Senate)---------> | header13 = {{#if:{{{majority_leader|}}}|{{{majority_leader}}} {{#if:{{{state_senate|}}}|[[Majority Leader of the {{{state_senate}}} Senate]]|[[United States Senate Majority Leader]]}} }} <!--------Majority Floor Leader (State Senate)---------> | header14 = {{#if:{{{majority_floor_leader|}}}|{{{majority_floor_leader}}} [[Majority Floor Leader of the {{{state_senate}}} Senate]] }} <!--------Minority Leader (State Senate)---------> | header15 = {{#if:{{{minority_leader|}}}|{{{minority_leader}}} [[Minority Leader of the {{{state_senate}}} Senate]] }} <!--------Minority Floor Leader (State Senate)---------> | header16 = {{#if:{{{minority_floor_leader|}}}|{{{minority_floor_leader}}} [[Minority Floor Leader of the {{{state_senate}}} Senate]] }} <!--------Congressman---------> | header17 = {{#if:{{{state_legislature|}}}{{{state_senate|}}}{{{jr/sr|}}}{{{jr/sr and state|}}}|| {{#if:{{#if:{{{state|}}}|{{{constituency|}}}}}{{{district|}}}{{{state_house|}}}|{{#if:{{{state_assembly|}}} |Member{{#if:{{{succeeding|}}}{{{assuming|}}}|-elect}} of the <span style="display: inline-block;">[[{{{state_assembly|}}} {{#ifeq:{{{state_assembly|}}}|Nevada||{{#ifeq:{{{state_assembly|}}}|New Jersey|General|State}}}} Assembly]]</span><br />from the |Member{{#if:{{{succeeding|}}}{{{assuming|}}}|-elect}} of the <span style="display: inline-block;">[[{{#if:{{{state_house|}}} |{{{state_house}}}|{{#if:{{{state_delegate|}}}|{{{state_delegate}}}|United States }}}} {{#if:{{{state_delegate|}}}|House of Delegates|House of Representatives}}|{{#if:{{{state_house|}}} |{{{state_house}}}|{{#if:{{{state_delegate|}}}|{{{state_delegate}}}|U.S.}}}}&#32;{{#if:{{{state_delegate|}}}|House&#32;of&#32;Delegates|{{#if:{{{state_house|}}}| }}House&#32;of&#32;Representatives}}]]</span>{{#if:{{{district|}}}{{{state|}}}{{{state_delegate|}}}{{{state_house|}}}|<br />from {{#if:{{{state_delegate|}}}|the |{{#if:{{{state_house|}}}|{{#if:{{{district|}}}|the|{{{state|}}}}}|{{{state|}}}{{#if:{{{district|}}}|'s}}}}}} }}}} {{#if:{{{district|}}}|{{{district}}} district|{{#if:{{{state_house|}}}|{{{constituency|}}}}}}}{{#if:{{{prior_term|}}}| <br />{{{prior_term}}}}} }} }} <!--------Convocation---------> | header18 = {{#if:{{{convocation|}}}|{{{convocation}}}}} <!--------Term---------> | data19 = {{#if:{{{termend|}}}{{{succeeding|}}}{{{assuming|}}}| {{#if:{{{status|}}} | <div style="width:100%; margin:0; background-color: {{{color|lavender}}}">'''{{{status}}}'''</div>|}}| }} | data20 = {{#if:{{{nominee|}}}{{{candidate|}}}|| {{#if:{{{succeeding|}}}{{{assuming|}}} | <span class="nowrap">'''ว่าที่ตำแหน่ง'''</span><br />{{{termstart}}}{{#if:{{{term|}}}{{{termend|}}}|[[Category:Pages using infobox officeholder with succeeding and term or termend]]}} | {{#if: {{{term|}}} | <span class="nowrap">'''{{{termlabel|ดำรงตำแหน่ง}}}'''</span><br />{{{term}}} }} }} }} | data21 = {{#if:{{{nominee|}}}{{{candidate|}}}|| {{#if:{{{succeeding|}}}{{{assuming|}}} | |{{#if:{{{termstart|}}} | {{#if:{{{termend|}}} |<!--then: term has start and end:--><span class="nowrap">'''{{{termlabel|ดำรงตำแหน่ง}}}'''</span><br />{{en dash range|{{{termstart}}}|{{{termend}}}}}{{#if:{{{alongside|}}}{{{co-leader|}}}|<div style="line-height:normal; padding-top:0.2em; padding-bottom:0.1em">{{#if:{{{alongside|}}}|ดำรงตำแหน่ง|เป็นผู้นำ}}ร่วมกับ{{#if:{{{alongside|}}}|{{{alongside}}}|{{{co-leader}}}}}</div>}} |{{#if:{{{status|}}}|<div style="width:100%; margin:0; background-color: {{{color|lavender}}}">'''{{{status}}}'''</div>|<!--else: term is ongoing--><div style="width:100%; margin:0; background-color: {{{color|lavender}}}">'''[[การดำรงตำแหน่ง|อยู่ในวาระ]]'''</div>}} }} }} }} }} | data22 = {{#if:{{{nominee|}}}{{{candidate|}}}|| {{#if:{{{succeeding|}}}{{{assuming|}}} | |{{#if:{{{termstart|}}} |{{#if:{{{termend|}}} |<!--then nothing else; term has ended--> |<!--else term is ongoing:--><span class="nowrap">'''{{#if:{{{termlabel|}}}|{{str rep|1={{{termlabel}}}|2=ดำรงตำแหน่ง|3=เริ่มดำรงตำแหน่ง}}|เริ่มดำรงตำแหน่ง}}'''</span>&#32;<br />{{{termstart}}}{{#if:{{{alongside|}}}{{{co-leader|}}}|<div style="line-height:normal; padding-top:0.2em; padding-bottom:0.1em">{{#if:{{{alongside|}}}|ดำรงตำแหน่ง|เป็นผู้นำ}}ร่วมกับ{{#if:{{{alongside|}}}|{{{alongside}}}|{{{co-leader}}}}}</div>}} }} }} }} }} }} }}<!-- end infobox1 / start infobox2 -->{{#if:{{{monarch|}}}{{{president|}}}{{{governor-general|}}}{{{governor_general|}}}{{{primeminister|}}}{{{chancellor|}}}{{{minister|}}}{{{taoiseach|}}}{{{firstminister|}}}{{{chiefminister|}}}{{{premier|}}}{{{governor|}}}{{{lieutenant_governor|}}}{{{vicepresident|}}}{{{vicegovernor|}}}{{{viceprimeminister|}}}{{{vicepremier|}}}{{{deputy|}}}{{{leader|}}}{{{lieutenant|}}}{{{nominator|}}}{{{appointer|}}}{{{opponent|}}}{{{incumbent|}}}{{{succeeding|}}}{{{assuming|}}}{{{preceding|}}}{{{predecessor|}}}{{{preceded|}}}{{{successor|}}}{{{succeeded|}}}{{{parliamentarygroup|}}}{{{constituency|}}}{{{majority|}}}{{{suboffice|}}}{{{1namedata|}}}{{{2namedata|}}}{{{3namedata|}}}{{{4namedata|}}}{{{5namedata|}}}{{{runningmate|}}}| {{#invoke:infobox|infoboxTemplate|child=yes | labelstyle = text-align:left | label1 = {{nowrap|เสนอชื่อโดย}} | data1 = {{{nominator|}}} | label2 = {{nowrap|แต่งตั้งโดย}} | data2 = {{{appointer|}}} <!--------President, Prime Minister, Governor---------> | label3 = กษัตริย์ | data3 = {{{monarch|}}} | label4 = ประธานาธิบดี | data4 = {{{president|}}} | label5 = {{nowrap|ผู้สำเร็จราชการแทนพระองค์}} | data5 = {{#if:{{{governor_general|}}}|{{{governor_general}}}|{{{governor-general|}}}}} | label6 = {{nowrap|นายกรัฐมนตรี}} | data6 = {{{primeminister|}}} | label7 = หัวหน้ารัฐบาล | data7 = {{{chancellor|}}} | label8 = รัฐมนตรี | data8 = {{{minister|}}} | label9 = ทีเชิฆ | data9 = {{{taoiseach|}}} | label10 = {{nowrap|มุขมนตรี}} | data10 = {{{firstminister|}}} | label11 = {{nowrap|หัวหน้ารัฐบาล}} | data11 = {{{chiefminister|}}} | label12 = หัวหน้ารัฐบาล | data12 = {{{premier|}}} | label13 = ผู้ว่าราชการ | data13 = {{{governor|}}} | label14 = รองผู้ว่าราชการ | data14 = {{{lieutenant_governor|}}} <!--------Vice president/s, Vice Prime Minister/s, Deputy/ies, Lieutenant/s---------> | label15 = <span class="nowrap">{{#if:{{{office|}}}|{{#ifeq:{{isValidPageName|รอง{{{office}}}}}|valid|[[รอง{{{office}}}|รองประธานาธิบดี]]|รองประธานาธิบดี}}|รองประธานาธิบดี}}</span> | data15 = {{{vicepresident|}}} | label16 = <span class="nowrap">{{#if:{{{office|}}}|{{#ifeq:{{isValidPageName|รอง{{{office}}}}}|valid|[[รอง{{{office}}}|รองผู้ว่าการ]]|รองผู้ว่าการ}}|รองผู้ว่าการ}}</span> | data16 = {{{vicegovernor|}}} | label17 = <span class="nowrap">{{#if:{{{office|}}}|[[รอง{{{office}}}|รองนายกรัฐมนตรี]]|รอง[[นายกรัฐมนตรี]]}}</span> | data17 = {{{viceprimeminister|}}} | label18 = <span class="nowrap">{{#if:{{{office|}}}|{{#ifeq:{{isValidPageName|รอง{{{office}}}}}|valid|[[รอง{{{office}}}|รองหัวหน้ารัฐบาล]]|รองหัวหน้ารัฐบาล}}|รองหัวหน้ารัฐบาล}}</span> | data18 = {{{vicepremier|}}} | label19 = {{#if:{{{office|}}}|{{#ifeq:{{isValidPageName|รอง{{{office}}}}}|valid|[[รอง{{{office}}}|รอง]]|รอง}}|รอง}} | data19 = {{{deputy|}}} | label20 = รัฐมนตรีช่วย | data20 = {{{deputyminister|}}} | label21 = รัฐมนตรีว่าการ | data21 = {{{headminister|}}} | label22 = ผู้นำ | data22 = {{{leader|}}} | label23 = {{#if:{{{office|}}}|[[รักษาการแทน{{{office}}}|รักษาการแทน]]|รักษาการแทน}} | data23 = {{{lieutenant|}}} | label24 = {{nowrap|{{{subterm|}}}}} | data24 = {{{suboffice|}}} <!--------Blank fields---------> | label25 = {{{1blankname|}}} | data25 = {{{1namedata|}}} | label26 = {{{2blankname|}}} | data26 = {{{2namedata|}}} | label27 = {{{3blankname|}}} | data27 = {{{3namedata|}}} | label28 = {{{4blankname|}}} | data28 = {{{4namedata|}}} | label29 = {{{5blankname|}}} | data29 = {{{5namedata|}}} <!--------Predecessor/successor---------> | label30 = <span class="nowrap">ผู้ร่วมหาเสียง</span> | data30 = {{{runningmate|}}} | label31 = คู่แข่ง | data31 = {{{opponent|}}} | label32 = อยู่ในวาระ | data32 = {{{incumbent|}}} | label33 = {{#if:{{{succeeding|}}}|รับช่วงจาก|ส่งต่อให้}} | data33 = {{#if:{{{succeeding|}}}|{{{succeeding|}}}|{{{preceding|}}}}} | label34 = <span class="nowrap">ก่อนหน้า</span> | data34 = {{#if:{{{succeeding|}}}||{{#if:{{{predecessor|}}}|{{{predecessor}}}|{{{preceded|}}}}}}} | label35 = <span class="nowrap">ถัดไป</span> | data35 = {{#if:{{{succeeding|}}}||{{#switch:{{#if:{{{successor|}}}|{{{successor}}}|{{{succeeded|}}}}} | อยู่ในตำแหน่ง | '''อยู่ในตำแหน่ง''' | ''อยู่ในตำแหน่ง'' | [[การดำรงตำแหน่ง|อยู่ในตำแหน่ง]] | อยู่ในตำแหน่ง | '''อยู่ในตำแหน่ง''' | ''อยู่ในตำแหน่ง'' | [[การดำรงตำแหน่ง|อยู่ในตำแหน่ง]] = | #default = {{#if:{{{successor|}}}|{{{successor}}}|{{{succeeded|}}}}} }}}} <!--------Constituency/Majority---------> | label36 = [[กลุ่มรัฐสภา]] | data36 = {{{parliamentarygroup|}}} | label37 = เขตเลือกตั้ง | data37 = {{{constituency|}}} | label38 = คะแนนเสียง | data38 = {{{majority|}}} }} }}<noinclude> {{คู่มือการใช้งาน}} </noinclude> 87c1a6c0b2d52aa8c5d2acb283e6825dab3352e3 แม่แบบ:PAGENAMEBASE 10 17 27 2023-10-05T10:32:00Z PeachFullzZ 2 สร้างหน้าด้วย "{{{{{|safesubst:}}}#Invoke:String|replace|{{{1|{{{{{|safesubst:}}}PAGENAME}}}}}|%s+%b()$||1|false}}<noinclude> {{documentation}} </noinclude>" wikitext text/x-wiki {{{{{|safesubst:}}}#Invoke:String|replace|{{{1|{{{{{|safesubst:}}}PAGENAME}}}}}|%s+%b()$||1|false}}<noinclude> {{documentation}} </noinclude> f23a5d434cb5b0baac5e1f58e9ceef9118e6873f 30 27 2023-10-05T10:34:27Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:PAGENAMEBASE]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki {{{{{|safesubst:}}}#Invoke:String|replace|{{{1|{{{{{|safesubst:}}}PAGENAME}}}}}|%s+%b()$||1|false}}<noinclude> {{documentation}} </noinclude> f23a5d434cb5b0baac5e1f58e9ceef9118e6873f มอดูล:String 828 18 28 2023-10-05T10:33:43Z PeachFullzZ 2 สร้างหน้าด้วย "--[[ This module is intended to provide access to basic string functions. Most of the functions provided here can be invoked with named parameters, unnamed parameters, or a mixture. If named parameters are used, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. Depending on the intended use, it may be advantageous to either preserve or remove such whitespace. Global options ignore_errors: If set to 't..." Scribunto text/plain --[[ This module is intended to provide access to basic string functions. Most of the functions provided here can be invoked with named parameters, unnamed parameters, or a mixture. If named parameters are used, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. Depending on the intended use, it may be advantageous to either preserve or remove such whitespace. Global options ignore_errors: If set to 'true' or 1, any error condition will result in an empty string being returned rather than an error message. error_category: If an error occurs, specifies the name of a category to include with the error message. The default category is [Category:Errors reported by Module String]. no_category: If set to 'true' or 1, no category will be added if an error is generated. Unit tests for this module are available at Module:String/tests. ]] local str = {} --[[ len This function returns the length of the target string. Usage: {{#invoke:String|len|target_string|}} OR {{#invoke:String|len|s=target_string}} Parameters s: The string whose length to report If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. ]] function str.len( frame ) local new_args = str._getParameters( frame.args, {'s'} ) local s = new_args['s'] or '' return mw.ustring.len( s ) end --[[ sub This function returns a substring of the target string at specified indices. Usage: {{#invoke:String|sub|target_string|start_index|end_index}} OR {{#invoke:String|sub|s=target_string|i=start_index|j=end_index}} Parameters s: The string to return a subset of i: The fist index of the substring to return, defaults to 1. j: The last index of the string to return, defaults to the last character. The first character of the string is assigned an index of 1. If either i or j is a negative value, it is interpreted the same as selecting a character by counting from the end of the string. Hence, a value of -1 is the same as selecting the last character of the string. If the requested indices are out of range for the given string, an error is reported. ]] function str.sub( frame ) local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } ) local s = new_args['s'] or '' local i = tonumber( new_args['i'] ) or 1 local j = tonumber( new_args['j'] ) or -1 local len = mw.ustring.len( s ) -- Convert negatives for range checking if i < 0 then i = len + i + 1 end if j < 0 then j = len + j + 1 end if i > len or j > len or i < 1 or j < 1 then return str._error( 'String subset index out of range' ) end if j < i then return str._error( 'String subset indices out of order' ) end return mw.ustring.sub( s, i, j ) end --[[ This function implements that features of {{str sub old}} and is kept in order to maintain these older templates. ]] function str.sublength( frame ) local i = tonumber( frame.args.i ) or 0 local len = tonumber( frame.args.len ) return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) ) end --[[ _match This function returns a substring from the source string that matches a specified pattern. It is exported for use in other modules Usage: strmatch = require("Module:String")._match sresult = strmatch( s, pattern, start, match, plain, nomatch ) Parameters s: The string to search pattern: The pattern or string to find within the string start: The index within the source string to start the search. The first character of the string has index 1. Defaults to 1. match: In some cases it may be possible to make multiple matches on a single string. This specifies which match to return, where the first match is match= 1. If a negative number is specified then a match is returned counting from the last match. Hence match = -1 is the same as requesting the last match. Defaults to 1. plain: A flag indicating that the pattern should be understood as plain text. Defaults to false. nomatch: If no match is found, output the "nomatch" value rather than an error. For information on constructing Lua patterns, a form of [regular expression], see: * http://www.lua.org/manual/5.1/manual.html#5.4.1 * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns ]] -- This sub-routine is exported for use in other modules function str._match( s, pattern, start, match_index, plain_flag, nomatch ) if s == '' then return str._error( 'Target string is empty' ) end if pattern == '' then return str._error( 'Pattern string is empty' ) end start = tonumber(start) or 1 if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then return str._error( 'Requested start is out of range' ) end if match_index == 0 then return str._error( 'Match index is out of range' ) end if plain_flag then pattern = str._escapePattern( pattern ) end local result if match_index == 1 then -- Find first match is simple case result = mw.ustring.match( s, pattern, start ) else if start > 1 then s = mw.ustring.sub( s, start ) end local iterator = mw.ustring.gmatch(s, pattern) if match_index > 0 then -- Forward search for w in iterator do match_index = match_index - 1 if match_index == 0 then result = w break end end else -- Reverse search local result_table = {} local count = 1 for w in iterator do result_table[count] = w count = count + 1 end result = result_table[ count + match_index ] end end if result == nil then if nomatch == nil then return str._error( 'Match not found' ) else return nomatch end else return result end end --[[ match This function returns a substring from the source string that matches a specified pattern. Usage: {{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}} OR {{#invoke:String|match|s=source_string|pattern=pattern_string|start=start_index |match=match_number|plain=plain_flag|nomatch=nomatch_output}} Parameters s: The string to search pattern: The pattern or string to find within the string start: The index within the source string to start the search. The first character of the string has index 1. Defaults to 1. match: In some cases it may be possible to make multiple matches on a single string. This specifies which match to return, where the first match is match= 1. If a negative number is specified then a match is returned counting from the last match. Hence match = -1 is the same as requesting the last match. Defaults to 1. plain: A flag indicating that the pattern should be understood as plain text. Defaults to false. nomatch: If no match is found, output the "nomatch" value rather than an error. If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from each string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. If the match_number or start_index are out of range for the string being queried, then this function generates an error. An error is also generated if no match is found. If one adds the parameter ignore_errors=true, then the error will be suppressed and an empty string will be returned on any failure. For information on constructing Lua patterns, a form of [regular expression], see: * http://www.lua.org/manual/5.1/manual.html#5.4.1 * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns ]] -- This is the entry point for #invoke:String|match function str.match( frame ) local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} ) local s = new_args['s'] or '' local start = tonumber( new_args['start'] ) or 1 local plain_flag = str._getBoolean( new_args['plain'] or false ) local pattern = new_args['pattern'] or '' local match_index = math.floor( tonumber(new_args['match']) or 1 ) local nomatch = new_args['nomatch'] return str._match( s, pattern, start, match_index, plain_flag, nomatch ) end --[[ pos This function returns a single character from the target string at position pos. Usage: {{#invoke:String|pos|target_string|index_value}} OR {{#invoke:String|pos|target=target_string|pos=index_value}} Parameters target: The string to search pos: The index for the character to return If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. The first character has an index value of 1. If one requests a negative value, this function will select a character by counting backwards from the end of the string. In other words pos = -1 is the same as asking for the last character. A requested value of zero, or a value greater than the length of the string returns an error. ]] function str.pos( frame ) local new_args = str._getParameters( frame.args, {'target', 'pos'} ) local target_str = new_args['target'] or '' local pos = tonumber( new_args['pos'] ) or 0 if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then return str._error( 'String index out of range' ) end return mw.ustring.sub( target_str, pos, pos ) end --[[ str_find This function duplicates the behavior of {{str_find}}, including all of its quirks. This is provided in order to support existing templates, but is NOT RECOMMENDED for new code and templates. New code is recommended to use the "find" function instead. Returns the first index in "source" that is a match to "target". Indexing is 1-based, and the function returns -1 if the "target" string is not present in "source". Important Note: If the "target" string is empty / missing, this function returns a value of "1", which is generally unexpected behavior, and must be accounted for separatetly. ]] function str.str_find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target'} ) local source_str = new_args['source'] or '' local target_str = new_args['target'] or '' if target_str == '' then return 1 end local start = mw.ustring.find( source_str, target_str, 1, true ) if start == nil then start = -1 end return start end --[[ find This function allows one to search for a target string or pattern within another string. Usage: {{#invoke:String|find|source_str|target_string|start_index|plain_flag}} OR {{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}} Parameters source: The string to search target: The string or pattern to find within source start: The index within the source string to start the search, defaults to 1 plain: Boolean flag indicating that target should be understood as plain text and not as a Lua style regular expression, defaults to true If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. This function returns the first index >= "start" where "target" can be found within "source". Indices are 1-based. If "target" is not found, then this function returns 0. If either "source" or "target" are missing / empty, this function also returns 0. This function should be safe for UTF-8 strings. ]] function str.find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } ) local source_str = new_args['source'] or '' local pattern = new_args['target'] or '' local start_pos = tonumber(new_args['start']) or 1 local plain = new_args['plain'] or true if source_str == '' or pattern == '' then return 0 end plain = str._getBoolean( plain ) local start = mw.ustring.find( source_str, pattern, start_pos, plain ) if start == nil then start = 0 end return start end --[[ replace This function allows one to replace a target string or pattern within another string. Usage: {{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}} OR {{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string| count=replacement_count|plain=plain_flag}} Parameters source: The string to search pattern: The string or pattern to find within source replace: The replacement text count: The number of occurences to replace, defaults to all. plain: Boolean flag indicating that pattern should be understood as plain text and not as a Lua style regular expression, defaults to true ]] function str.replace( frame ) local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } ) local source_str = new_args['source'] or '' local pattern = new_args['pattern'] or '' local replace = new_args['replace'] or '' local count = tonumber( new_args['count'] ) local plain = new_args['plain'] or true if source_str == '' or pattern == '' then return source_str end plain = str._getBoolean( plain ) if plain then pattern = str._escapePattern( pattern ) replace = mw.ustring.gsub( replace, "%%", "%%%%" ) --Only need to escape replacement sequences. end local result if count ~= nil then result = mw.ustring.gsub( source_str, pattern, replace, count ) else result = mw.ustring.gsub( source_str, pattern, replace ) end return result end --[[ simple function to pipe string.rep to templates. ]] function str.rep( frame ) local repetitions = tonumber( frame.args[2] ) if not repetitions then return str._error( 'function rep expects a number as second parameter, received "' .. ( frame.args[2] or '' ) .. '"' ) end return string.rep( frame.args[1] or '', repetitions ) end --[[ escapePattern This function escapes special characters from a Lua string pattern. See [1] for details on how patterns work. [1] https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns Usage: {{#invoke:String|escapePattern|pattern_string}} Parameters pattern_string: The pattern string to escape. ]] function str.escapePattern( frame ) local pattern_str = frame.args[1] if not pattern_str then return str._error( 'No pattern string specified' ) end local result = str._escapePattern( pattern_str ) return result end --[[ count This function counts the number of occurrences of one string in another. ]] function str.count(frame) local args = str._getParameters(frame.args, {'source', 'pattern', 'plain'}) local source = args.source or '' local pattern = args.pattern or '' local plain = str._getBoolean(args.plain or true) if plain then pattern = str._escapePattern(pattern) end local _, count = mw.ustring.gsub(source, pattern, '') return count end --[[ endswith This function determines whether a string ends with another string. ]] function str.endswith(frame) local args = str._getParameters(frame.args, {'source', 'pattern'}) local source = args.source or '' local pattern = args.pattern or '' if pattern == '' then -- All strings end with the empty string. return "yes" end if mw.ustring.sub(source, -mw.ustring.len(pattern), -1) == pattern then return "yes" else return "" end end --[[ join Join all non empty arguments together; the first argument is the separator. Usage: {{#invoke:String|join|sep|one|two|three}} ]] function str.join(frame) local args = {} local sep for _, v in ipairs( frame.args ) do if sep then if v ~= '' then table.insert(args, v) end else sep = v end end return table.concat( args, sep or '' ) end --[[ Helper function that populates the argument list given that user may need to use a mix of named and unnamed parameters. This is relevant because named parameters are not identical to unnamed parameters due to string trimming, and when dealing with strings we sometimes want to either preserve or remove that whitespace depending on the application. ]] function str._getParameters( frame_args, arg_list ) local new_args = {} local index = 1 local value for _, arg in ipairs( arg_list ) do value = frame_args[arg] if value == nil then value = frame_args[index] index = index + 1 end new_args[arg] = value end return new_args end --[[ Helper function to handle error messages. ]] function str._error( error_str ) local frame = mw.getCurrentFrame() local error_category = frame.args.error_category or 'Errors reported by Module String' local ignore_errors = frame.args.ignore_errors or false local no_category = frame.args.no_category or false if str._getBoolean(ignore_errors) then return '' end local error_str = '<strong class="error">String Module Error: ' .. error_str .. '</strong>' if error_category ~= '' and not str._getBoolean( no_category ) then error_str = '[[Category:' .. error_category .. ']]' .. error_str end return error_str end --[[ Helper Function to interpret boolean strings ]] function str._getBoolean( boolean_str ) local boolean_value if type( boolean_str ) == 'string' then boolean_str = boolean_str:lower() if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0' or boolean_str == '' then boolean_value = false else boolean_value = true end elseif type( boolean_str ) == 'boolean' then boolean_value = boolean_str else error( 'No boolean value found' ) end return boolean_value end --[[ Helper function that escapes all pattern characters so that they will be treated as plain text. ]] function str._escapePattern( pattern_str ) return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ) end return str 6df794dd52434e0f6a372c9918f5a9dedd15f579 29 28 2023-10-05T10:34:06Z PeachFullzZ 2 ป้องกัน "[[มอดูล:String]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain --[[ This module is intended to provide access to basic string functions. Most of the functions provided here can be invoked with named parameters, unnamed parameters, or a mixture. If named parameters are used, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. Depending on the intended use, it may be advantageous to either preserve or remove such whitespace. Global options ignore_errors: If set to 'true' or 1, any error condition will result in an empty string being returned rather than an error message. error_category: If an error occurs, specifies the name of a category to include with the error message. The default category is [Category:Errors reported by Module String]. no_category: If set to 'true' or 1, no category will be added if an error is generated. Unit tests for this module are available at Module:String/tests. ]] local str = {} --[[ len This function returns the length of the target string. Usage: {{#invoke:String|len|target_string|}} OR {{#invoke:String|len|s=target_string}} Parameters s: The string whose length to report If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. ]] function str.len( frame ) local new_args = str._getParameters( frame.args, {'s'} ) local s = new_args['s'] or '' return mw.ustring.len( s ) end --[[ sub This function returns a substring of the target string at specified indices. Usage: {{#invoke:String|sub|target_string|start_index|end_index}} OR {{#invoke:String|sub|s=target_string|i=start_index|j=end_index}} Parameters s: The string to return a subset of i: The fist index of the substring to return, defaults to 1. j: The last index of the string to return, defaults to the last character. The first character of the string is assigned an index of 1. If either i or j is a negative value, it is interpreted the same as selecting a character by counting from the end of the string. Hence, a value of -1 is the same as selecting the last character of the string. If the requested indices are out of range for the given string, an error is reported. ]] function str.sub( frame ) local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } ) local s = new_args['s'] or '' local i = tonumber( new_args['i'] ) or 1 local j = tonumber( new_args['j'] ) or -1 local len = mw.ustring.len( s ) -- Convert negatives for range checking if i < 0 then i = len + i + 1 end if j < 0 then j = len + j + 1 end if i > len or j > len or i < 1 or j < 1 then return str._error( 'String subset index out of range' ) end if j < i then return str._error( 'String subset indices out of order' ) end return mw.ustring.sub( s, i, j ) end --[[ This function implements that features of {{str sub old}} and is kept in order to maintain these older templates. ]] function str.sublength( frame ) local i = tonumber( frame.args.i ) or 0 local len = tonumber( frame.args.len ) return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) ) end --[[ _match This function returns a substring from the source string that matches a specified pattern. It is exported for use in other modules Usage: strmatch = require("Module:String")._match sresult = strmatch( s, pattern, start, match, plain, nomatch ) Parameters s: The string to search pattern: The pattern or string to find within the string start: The index within the source string to start the search. The first character of the string has index 1. Defaults to 1. match: In some cases it may be possible to make multiple matches on a single string. This specifies which match to return, where the first match is match= 1. If a negative number is specified then a match is returned counting from the last match. Hence match = -1 is the same as requesting the last match. Defaults to 1. plain: A flag indicating that the pattern should be understood as plain text. Defaults to false. nomatch: If no match is found, output the "nomatch" value rather than an error. For information on constructing Lua patterns, a form of [regular expression], see: * http://www.lua.org/manual/5.1/manual.html#5.4.1 * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns ]] -- This sub-routine is exported for use in other modules function str._match( s, pattern, start, match_index, plain_flag, nomatch ) if s == '' then return str._error( 'Target string is empty' ) end if pattern == '' then return str._error( 'Pattern string is empty' ) end start = tonumber(start) or 1 if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then return str._error( 'Requested start is out of range' ) end if match_index == 0 then return str._error( 'Match index is out of range' ) end if plain_flag then pattern = str._escapePattern( pattern ) end local result if match_index == 1 then -- Find first match is simple case result = mw.ustring.match( s, pattern, start ) else if start > 1 then s = mw.ustring.sub( s, start ) end local iterator = mw.ustring.gmatch(s, pattern) if match_index > 0 then -- Forward search for w in iterator do match_index = match_index - 1 if match_index == 0 then result = w break end end else -- Reverse search local result_table = {} local count = 1 for w in iterator do result_table[count] = w count = count + 1 end result = result_table[ count + match_index ] end end if result == nil then if nomatch == nil then return str._error( 'Match not found' ) else return nomatch end else return result end end --[[ match This function returns a substring from the source string that matches a specified pattern. Usage: {{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}} OR {{#invoke:String|match|s=source_string|pattern=pattern_string|start=start_index |match=match_number|plain=plain_flag|nomatch=nomatch_output}} Parameters s: The string to search pattern: The pattern or string to find within the string start: The index within the source string to start the search. The first character of the string has index 1. Defaults to 1. match: In some cases it may be possible to make multiple matches on a single string. This specifies which match to return, where the first match is match= 1. If a negative number is specified then a match is returned counting from the last match. Hence match = -1 is the same as requesting the last match. Defaults to 1. plain: A flag indicating that the pattern should be understood as plain text. Defaults to false. nomatch: If no match is found, output the "nomatch" value rather than an error. If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from each string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. If the match_number or start_index are out of range for the string being queried, then this function generates an error. An error is also generated if no match is found. If one adds the parameter ignore_errors=true, then the error will be suppressed and an empty string will be returned on any failure. For information on constructing Lua patterns, a form of [regular expression], see: * http://www.lua.org/manual/5.1/manual.html#5.4.1 * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns ]] -- This is the entry point for #invoke:String|match function str.match( frame ) local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} ) local s = new_args['s'] or '' local start = tonumber( new_args['start'] ) or 1 local plain_flag = str._getBoolean( new_args['plain'] or false ) local pattern = new_args['pattern'] or '' local match_index = math.floor( tonumber(new_args['match']) or 1 ) local nomatch = new_args['nomatch'] return str._match( s, pattern, start, match_index, plain_flag, nomatch ) end --[[ pos This function returns a single character from the target string at position pos. Usage: {{#invoke:String|pos|target_string|index_value}} OR {{#invoke:String|pos|target=target_string|pos=index_value}} Parameters target: The string to search pos: The index for the character to return If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. The first character has an index value of 1. If one requests a negative value, this function will select a character by counting backwards from the end of the string. In other words pos = -1 is the same as asking for the last character. A requested value of zero, or a value greater than the length of the string returns an error. ]] function str.pos( frame ) local new_args = str._getParameters( frame.args, {'target', 'pos'} ) local target_str = new_args['target'] or '' local pos = tonumber( new_args['pos'] ) or 0 if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then return str._error( 'String index out of range' ) end return mw.ustring.sub( target_str, pos, pos ) end --[[ str_find This function duplicates the behavior of {{str_find}}, including all of its quirks. This is provided in order to support existing templates, but is NOT RECOMMENDED for new code and templates. New code is recommended to use the "find" function instead. Returns the first index in "source" that is a match to "target". Indexing is 1-based, and the function returns -1 if the "target" string is not present in "source". Important Note: If the "target" string is empty / missing, this function returns a value of "1", which is generally unexpected behavior, and must be accounted for separatetly. ]] function str.str_find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target'} ) local source_str = new_args['source'] or '' local target_str = new_args['target'] or '' if target_str == '' then return 1 end local start = mw.ustring.find( source_str, target_str, 1, true ) if start == nil then start = -1 end return start end --[[ find This function allows one to search for a target string or pattern within another string. Usage: {{#invoke:String|find|source_str|target_string|start_index|plain_flag}} OR {{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}} Parameters source: The string to search target: The string or pattern to find within source start: The index within the source string to start the search, defaults to 1 plain: Boolean flag indicating that target should be understood as plain text and not as a Lua style regular expression, defaults to true If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. This function returns the first index >= "start" where "target" can be found within "source". Indices are 1-based. If "target" is not found, then this function returns 0. If either "source" or "target" are missing / empty, this function also returns 0. This function should be safe for UTF-8 strings. ]] function str.find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } ) local source_str = new_args['source'] or '' local pattern = new_args['target'] or '' local start_pos = tonumber(new_args['start']) or 1 local plain = new_args['plain'] or true if source_str == '' or pattern == '' then return 0 end plain = str._getBoolean( plain ) local start = mw.ustring.find( source_str, pattern, start_pos, plain ) if start == nil then start = 0 end return start end --[[ replace This function allows one to replace a target string or pattern within another string. Usage: {{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}} OR {{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string| count=replacement_count|plain=plain_flag}} Parameters source: The string to search pattern: The string or pattern to find within source replace: The replacement text count: The number of occurences to replace, defaults to all. plain: Boolean flag indicating that pattern should be understood as plain text and not as a Lua style regular expression, defaults to true ]] function str.replace( frame ) local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } ) local source_str = new_args['source'] or '' local pattern = new_args['pattern'] or '' local replace = new_args['replace'] or '' local count = tonumber( new_args['count'] ) local plain = new_args['plain'] or true if source_str == '' or pattern == '' then return source_str end plain = str._getBoolean( plain ) if plain then pattern = str._escapePattern( pattern ) replace = mw.ustring.gsub( replace, "%%", "%%%%" ) --Only need to escape replacement sequences. end local result if count ~= nil then result = mw.ustring.gsub( source_str, pattern, replace, count ) else result = mw.ustring.gsub( source_str, pattern, replace ) end return result end --[[ simple function to pipe string.rep to templates. ]] function str.rep( frame ) local repetitions = tonumber( frame.args[2] ) if not repetitions then return str._error( 'function rep expects a number as second parameter, received "' .. ( frame.args[2] or '' ) .. '"' ) end return string.rep( frame.args[1] or '', repetitions ) end --[[ escapePattern This function escapes special characters from a Lua string pattern. See [1] for details on how patterns work. [1] https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns Usage: {{#invoke:String|escapePattern|pattern_string}} Parameters pattern_string: The pattern string to escape. ]] function str.escapePattern( frame ) local pattern_str = frame.args[1] if not pattern_str then return str._error( 'No pattern string specified' ) end local result = str._escapePattern( pattern_str ) return result end --[[ count This function counts the number of occurrences of one string in another. ]] function str.count(frame) local args = str._getParameters(frame.args, {'source', 'pattern', 'plain'}) local source = args.source or '' local pattern = args.pattern or '' local plain = str._getBoolean(args.plain or true) if plain then pattern = str._escapePattern(pattern) end local _, count = mw.ustring.gsub(source, pattern, '') return count end --[[ endswith This function determines whether a string ends with another string. ]] function str.endswith(frame) local args = str._getParameters(frame.args, {'source', 'pattern'}) local source = args.source or '' local pattern = args.pattern or '' if pattern == '' then -- All strings end with the empty string. return "yes" end if mw.ustring.sub(source, -mw.ustring.len(pattern), -1) == pattern then return "yes" else return "" end end --[[ join Join all non empty arguments together; the first argument is the separator. Usage: {{#invoke:String|join|sep|one|two|three}} ]] function str.join(frame) local args = {} local sep for _, v in ipairs( frame.args ) do if sep then if v ~= '' then table.insert(args, v) end else sep = v end end return table.concat( args, sep or '' ) end --[[ Helper function that populates the argument list given that user may need to use a mix of named and unnamed parameters. This is relevant because named parameters are not identical to unnamed parameters due to string trimming, and when dealing with strings we sometimes want to either preserve or remove that whitespace depending on the application. ]] function str._getParameters( frame_args, arg_list ) local new_args = {} local index = 1 local value for _, arg in ipairs( arg_list ) do value = frame_args[arg] if value == nil then value = frame_args[index] index = index + 1 end new_args[arg] = value end return new_args end --[[ Helper function to handle error messages. ]] function str._error( error_str ) local frame = mw.getCurrentFrame() local error_category = frame.args.error_category or 'Errors reported by Module String' local ignore_errors = frame.args.ignore_errors or false local no_category = frame.args.no_category or false if str._getBoolean(ignore_errors) then return '' end local error_str = '<strong class="error">String Module Error: ' .. error_str .. '</strong>' if error_category ~= '' and not str._getBoolean( no_category ) then error_str = '[[Category:' .. error_category .. ']]' .. error_str end return error_str end --[[ Helper Function to interpret boolean strings ]] function str._getBoolean( boolean_str ) local boolean_value if type( boolean_str ) == 'string' then boolean_str = boolean_str:lower() if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0' or boolean_str == '' then boolean_value = false else boolean_value = true end elseif type( boolean_str ) == 'boolean' then boolean_value = boolean_str else error( 'No boolean value found' ) end return boolean_value end --[[ Helper function that escapes all pattern characters so that they will be treated as plain text. ]] function str._escapePattern( pattern_str ) return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ) end return str 6df794dd52434e0f6a372c9918f5a9dedd15f579 แม่แบบ:CountryPrefixThe 10 19 31 2023-10-05T10:41:58Z PeachFullzZ 2 สร้างหน้าด้วย "<includeonly>{{{{{|safesubst:}}}#switch: {{{1|}}} | Austrian Empire | Bahamas | Batavian Republic | Belgian Congo | British Antarctic Territory | British Empire | British Virgin Islands | Bukharan People's Soviet Republic | Cape Colony | Captaincy General of Chile | Caribbean | Cayman Islands | Central African Republic | Channel Islands | Collectivity of Saint Martin | Colony of Natal | Colony of Santiago | Comoros | Congo Free State | Cook Islands..." wikitext text/x-wiki <includeonly>{{{{{|safesubst:}}}#switch: {{{1|}}} | Austrian Empire | Bahamas | Batavian Republic | Belgian Congo | British Antarctic Territory | British Empire | British Virgin Islands | Bukharan People's Soviet Republic | Cape Colony | Captaincy General of Chile | Caribbean | Cayman Islands | Central African Republic | Channel Islands | Collectivity of Saint Martin | Colony of Natal | Colony of Santiago | Comoros | Congo Free State | Cook Islands | Cossack Hetmanate | Crown Dependencies | Czech Republic | Danish colonial empire | Democratic Republic of the Congo | Dominican Republic | Dominion of Newfoundland | Donetsk People's Republic | Duchy of Nassau | Dutch Caribbean | Dutch East Indies | Dutch Empire | Dutch Republic | Empire of Brazil | Falkland Islands | Falkland Islands Dependencies | Faroe Islands | Federal Republic of Central America | Federated States of Micronesia | Federation of Rhodesia and Nyasaland | French Union | French colonial empire | Gambia | German Empire | German colonial empire | Greater Republic of Central America | Gilbert and Ellice Islands | Grand Duchy of Hesse | Grand Duchy of Tuscany | Habsburg monarchy | Habsburg Netherlands | Hawaiian Kingdom | Holy Roman Empire | Holy See | Inca civilization | Irish Free State | Isle of Man | Italian Empire | Japanese colonial empire | Kazakh Autonomous Socialist Soviet Republic | Kazakh Soviet Socialist Republic | Kingdom of Hanover | Kingdom of Hawaii | Kingdom of Jerusalem | Kingdom of Naples | Kingdom of Sardinia | Kingdom of Sicily | Kingdom of the Two Sicilies | Kirghiz Soviet Socialist Republic | Luhansk People's Republic | Maldives | Mamluk Sultanate | Maratha Empire | Marshall Islands | Moldavian Autonomous Soviet Socialist Republic | Moldavian Soviet Socialist Republic | Mongol Empire | Mughal Empire | Nagorno-Karabakh Republic | Netherlands | Netherlands Antilles | New Hebrides | Northern Mariana Islands | Orange Free State | Ottoman Empire | Palestinian territories | Papal States | Philippines | Pitcairn Islands | Polish–Lithuanian Commonwealth | Portuguese Empire | Province of Quebec (1763–1791) | Republic of Artsakh | Republic of Florence | Republic of Genoa | Republic of Ireland | Republic of Macedonia | Republic of New Granada | Republic of Texas | Republic of the Congo | Republic of Venice | Russian Empire | Sahrawi Arab Democratic Republic | Socialist Republic of Macedonia | Solomon Islands | South African Republic | Southern Nigeria Protectorate | Soviet Union | Spanish East Indies | Spanish Empire | Spanish West Indies | State of Palestine | Straits Settlements | Swedish colonial empire | Territory of Papua | Thirteen Colonies | Trucial States | Trust Territory of the Pacific Islands | Turkmen Soviet Socialist Republic | Turks and Caicos Islands | United Arab Emirates | United Kingdom | United States | United States Virgin Islands | Viceroyalty of New Granada | Viceroyalty of Peru | Viceroyalty of the Río de la Plata | Zulu Kingdom =<!-- -->{{#ifeq: {{Yesno-no|{{{capitalised|{{{capitalized|}}}}}}}}|yes|The|the}} {{#ifeq: {{Yesno-no|{{{onlythe|}}}}}|yes||{{{1|}}}}}<!-- -->|#default={{#ifeq: {{Yesno-no|{{{onlythe|}}}}}|yes||{{{1|}}}}}<!-- -->}}</includeonly><noinclude> {{Documentation}} </noinclude> fed009e885630af9150708cf0df3d0f2e3938c43 แม่แบบ:Br separated entries 10 20 32 2023-10-05T10:51:42Z PeachFullzZ 2 สร้างหน้าด้วย "{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|br}}<noinclude> {{documentation}} </noinclude>" wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:Separated entries|br}}<noinclude> {{documentation}} </noinclude> 2019f7fc383259e70d66e43cbd97a43d20889f1b มอดูล:Separated entries 828 21 33 2023-10-05T10:54:10Z PeachFullzZ 2 สร้างหน้าด้วย "-- This module takes positional parameters as input and concatenates them with -- an optional separator. The final separator (the "conjunction") can be -- specified independently, enabling natural-language lists like -- "foo, bar, baz and qux". The starting parameter can also be specified. local compressSparseArray = require('Module:TableTools').compressSparseArray local p = {} function p._main(args) local separator = args.separator -- Decode (..." Scribunto text/plain -- This module takes positional parameters as input and concatenates them with -- an optional separator. The final separator (the "conjunction") can be -- specified independently, enabling natural-language lists like -- "foo, bar, baz and qux". The starting parameter can also be specified. local compressSparseArray = require('Module:TableTools').compressSparseArray local p = {} function p._main(args) local separator = args.separator -- Decode (convert to Unicode) HTML escape sequences, such as "&#32;" for space. and mw.text.decode(args.separator) or '' local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator -- Discard values before the starting parameter. local start = tonumber(args.start) if start then for i = 1, start - 1 do args[i] = nil end end -- Discard named parameters. local values = compressSparseArray(args) return mw.text.listToText(values, separator, conjunction) end local function makeInvokeFunction(separator, conjunction, first) return function (frame) local args = require('Module:Arguments').getArgs(frame) args.separator = separator or args.separator args.conjunction = conjunction or args.conjunction args.first = first or args.first return p._main(args) end end p.main = makeInvokeFunction() p.br = makeInvokeFunction('<br />') p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain()) return p e80231ff3de01afd7f62a94e0a34dc1e67504085 34 33 2023-10-05T10:54:28Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Separated entries]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- This module takes positional parameters as input and concatenates them with -- an optional separator. The final separator (the "conjunction") can be -- specified independently, enabling natural-language lists like -- "foo, bar, baz and qux". The starting parameter can also be specified. local compressSparseArray = require('Module:TableTools').compressSparseArray local p = {} function p._main(args) local separator = args.separator -- Decode (convert to Unicode) HTML escape sequences, such as "&#32;" for space. and mw.text.decode(args.separator) or '' local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator -- Discard values before the starting parameter. local start = tonumber(args.start) if start then for i = 1, start - 1 do args[i] = nil end end -- Discard named parameters. local values = compressSparseArray(args) return mw.text.listToText(values, separator, conjunction) end local function makeInvokeFunction(separator, conjunction, first) return function (frame) local args = require('Module:Arguments').getArgs(frame) args.separator = separator or args.separator args.conjunction = conjunction or args.conjunction args.first = first or args.first return p._main(args) end end p.main = makeInvokeFunction() p.br = makeInvokeFunction('<br />') p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain()) return p e80231ff3de01afd7f62a94e0a34dc1e67504085 มอดูล:Check for unknown parameters 828 22 35 2023-10-05T10:56:16Z PeachFullzZ 2 สร้างหน้าด้วย "-- This module may be used to compare the arguments passed to the parent -- with a list of arguments, returning a specified result if an argument is -- not on the list local p = {} local function trim(s) return s:match('^%s*(.-)%s*$') end local function isnotempty(s) return s and s:match('%S') end local function clean(text) -- Return text cleaned for display and truncated if too long. -- Strip markers are replaced with dummy text representing..." Scribunto text/plain -- This module may be used to compare the arguments passed to the parent -- with a list of arguments, returning a specified result if an argument is -- not on the list local p = {} local function trim(s) return s:match('^%s*(.-)%s*$') end local function isnotempty(s) return s and s:match('%S') end local function clean(text) -- Return text cleaned for display and truncated if too long. -- Strip markers are replaced with dummy text representing the original wikitext. local pos, truncated local function truncate(text) if truncated then return '' end if mw.ustring.len(text) > 25 then truncated = true text = mw.ustring.sub(text, 1, 25) .. '...' end return mw.text.nowiki(text) end local parts = {} for before, tag, remainder in text:gmatch('([^\127]*)\127[^\127]*%-(%l+)%-[^\127]*\127()') do pos = remainder table.insert(parts, truncate(before) .. '&lt;' .. tag .. '&gt;...&lt;/' .. tag .. '&gt;') end table.insert(parts, truncate(text:sub(pos or 1))) return table.concat(parts) end function p._check(args, pargs) if type(args) ~= "table" or type(pargs) ~= "table" then -- TODO: error handling return end -- create the list of known args, regular expressions, and the return string local knownargs = {} local regexps = {} for k, v in pairs(args) do if type(k) == 'number' then v = trim(v) knownargs[v] = 1 elseif k:find('^regexp[1-9][0-9]*$') then table.insert(regexps, '^' .. v .. '$') end end -- loop over the parent args, and make sure they are on the list local ignoreblank = isnotempty(args['ignoreblank']) local showblankpos = isnotempty(args['showblankpositional']) local values = {} for k, v in pairs(pargs) do if type(k) == 'string' and knownargs[k] == nil then local knownflag = false for _, regexp in ipairs(regexps) do if mw.ustring.match(k, regexp) then knownflag = true break end end if not knownflag and ( not ignoreblank or isnotempty(v) ) then table.insert(values, clean(k)) end elseif type(k) == 'number' and knownargs[tostring(k)] == nil then local knownflag = false for _, regexp in ipairs(regexps) do if mw.ustring.match(tostring(k), regexp) then knownflag = true break end end if not knownflag and ( showblankpos or isnotempty(v) ) then table.insert(values, k .. ' = ' .. clean(v)) end end end -- add results to the output tables local res = {} if #values > 0 then local unknown_text = args['unknown'] or 'Found _VALUE_, ' if mw.getCurrentFrame():preprocess( "{{REVISIONID}}" ) == "" then local preview_text = args['preview'] if isnotempty(preview_text) then preview_text = require('Module:If preview')._warning({preview_text}) elseif preview == nil then preview_text = unknown_text end unknown_text = preview_text end for _, v in pairs(values) do -- Fix odd bug for | = which gets stripped to the empty string and -- breaks category links if v == '' then v = ' ' end -- avoid error with v = 'example%2' ("invalid capture index") local r = unknown_text:gsub('_VALUE_', {_VALUE_ = v}) table.insert(res, r) end end return table.concat(res) end function p.check(frame) local args = frame.args local pargs = frame:getParent().args return p._check(args, pargs) end return p 93db6d115d4328d2a5148bb42959105e367b663e มอดูล:TableTools 828 23 36 2023-10-05T10:57:26Z PeachFullzZ 2 สร้างหน้าด้วย "------------------------------------------------------------------------------------ -- TableTools -- -- -- -- This module includes a number of functions for dealing with Lua tables. -- -- It is a meta-module, meant to be called from other Lua modules, and should not -- -- be called directly from #..." Scribunto text/plain ------------------------------------------------------------------------------------ -- TableTools -- -- -- -- This module includes a number of functions for dealing with Lua tables. -- -- It is a meta-module, meant to be called from other Lua modules, and should not -- -- be called directly from #invoke. -- ------------------------------------------------------------------------------------ local libraryUtil = require('libraryUtil') local p = {} -- Define often-used variables and functions. local floor = math.floor local infinity = math.huge local checkType = libraryUtil.checkType local checkTypeMulti = libraryUtil.checkTypeMulti ------------------------------------------------------------------------------------ -- isPositiveInteger -- -- This function returns true if the given value is a positive integer, and false -- if not. Although it doesn't operate on tables, it is included here as it is -- useful for determining whether a given table key is in the array part or the -- hash part of a table. ------------------------------------------------------------------------------------ function p.isPositiveInteger(v) return type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity end ------------------------------------------------------------------------------------ -- isNan -- -- This function returns true if the given number is a NaN value, and false if -- not. Although it doesn't operate on tables, it is included here as it is useful -- for determining whether a value can be a valid table key. Lua will generate an -- error if a NaN is used as a table key. ------------------------------------------------------------------------------------ function p.isNan(v) return type(v) == 'number' and v ~= v end ------------------------------------------------------------------------------------ -- shallowClone -- -- This returns a clone of a table. The value returned is a new table, but all -- subtables and functions are shared. Metamethods are respected, but the returned -- table will have no metatable of its own. ------------------------------------------------------------------------------------ function p.shallowClone(t) checkType('shallowClone', 1, t, 'table') local ret = {} for k, v in pairs(t) do ret[k] = v end return ret end ------------------------------------------------------------------------------------ -- removeDuplicates -- -- This removes duplicate values from an array. Non-positive-integer keys are -- ignored. The earliest value is kept, and all subsequent duplicate values are -- removed, but otherwise the array order is unchanged. ------------------------------------------------------------------------------------ function p.removeDuplicates(arr) checkType('removeDuplicates', 1, arr, 'table') local isNan = p.isNan local ret, exists = {}, {} for _, v in ipairs(arr) do if isNan(v) then -- NaNs can't be table keys, and they are also unique, so we don't need to check existence. ret[#ret + 1] = v else if not exists[v] then ret[#ret + 1] = v exists[v] = true end end end return ret end ------------------------------------------------------------------------------------ -- numKeys -- -- This takes a table and returns an array containing the numbers of any numerical -- keys that have non-nil values, sorted in numerical order. ------------------------------------------------------------------------------------ function p.numKeys(t) checkType('numKeys', 1, t, 'table') local isPositiveInteger = p.isPositiveInteger local nums = {} for k in pairs(t) do if isPositiveInteger(k) then nums[#nums + 1] = k end end table.sort(nums) return nums end ------------------------------------------------------------------------------------ -- affixNums -- -- This takes a table and returns an array containing the numbers of keys with the -- specified prefix and suffix. For example, for the table -- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will return -- {1, 3, 6}. ------------------------------------------------------------------------------------ function p.affixNums(t, prefix, suffix) checkType('affixNums', 1, t, 'table') checkType('affixNums', 2, prefix, 'string', true) checkType('affixNums', 3, suffix, 'string', true) local function cleanPattern(s) -- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally. return s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1') end prefix = prefix or '' suffix = suffix or '' prefix = cleanPattern(prefix) suffix = cleanPattern(suffix) local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$' local nums = {} for k in pairs(t) do if type(k) == 'string' then local num = mw.ustring.match(k, pattern) if num then nums[#nums + 1] = tonumber(num) end end end table.sort(nums) return nums end ------------------------------------------------------------------------------------ -- numData -- -- Given a table with keys like {"foo1", "bar1", "foo2", "baz2"}, returns a table -- of subtables in the format -- {[1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'}}. -- Keys that don't end with an integer are stored in a subtable named "other". The -- compress option compresses the table so that it can be iterated over with -- ipairs. ------------------------------------------------------------------------------------ function p.numData(t, compress) checkType('numData', 1, t, 'table') checkType('numData', 2, compress, 'boolean', true) local ret = {} for k, v in pairs(t) do local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$') if num then num = tonumber(num) local subtable = ret[num] or {} if prefix == '' then -- Positional parameters match the blank string; put them at the start of the subtable instead. prefix = 1 end subtable[prefix] = v ret[num] = subtable else local subtable = ret.other or {} subtable[k] = v ret.other = subtable end end if compress then local other = ret.other ret = p.compressSparseArray(ret) ret.other = other end return ret end ------------------------------------------------------------------------------------ -- compressSparseArray -- -- This takes an array with one or more nil values, and removes the nil values -- while preserving the order, so that the array can be safely traversed with -- ipairs. ------------------------------------------------------------------------------------ function p.compressSparseArray(t) checkType('compressSparseArray', 1, t, 'table') local ret = {} local nums = p.numKeys(t) for _, num in ipairs(nums) do ret[#ret + 1] = t[num] end return ret end ------------------------------------------------------------------------------------ -- sparseIpairs -- -- This is an iterator for sparse arrays. It can be used like ipairs, but can -- handle nil values. ------------------------------------------------------------------------------------ function p.sparseIpairs(t) checkType('sparseIpairs', 1, t, 'table') local nums = p.numKeys(t) local i = 0 local lim = #nums return function () i = i + 1 if i <= lim then local key = nums[i] return key, t[key] else return nil, nil end end end ------------------------------------------------------------------------------------ -- size -- -- This returns the size of a key/value pair table. It will also work on arrays, -- but for arrays it is more efficient to use the # operator. ------------------------------------------------------------------------------------ function p.size(t) checkType('size', 1, t, 'table') local i = 0 for _ in pairs(t) do i = i + 1 end return i end local function defaultKeySort(item1, item2) -- "number" < "string", so numbers will be sorted before strings. local type1, type2 = type(item1), type(item2) if type1 ~= type2 then return type1 < type2 elseif type1 == 'table' or type1 == 'boolean' or type1 == 'function' then return tostring(item1) < tostring(item2) else return item1 < item2 end end ------------------------------------------------------------------------------------ -- keysToList -- -- Returns an array of the keys in a table, sorted using either a default -- comparison function or a custom keySort function. ------------------------------------------------------------------------------------ function p.keysToList(t, keySort, checked) if not checked then checkType('keysToList', 1, t, 'table') checkTypeMulti('keysToList', 2, keySort, {'function', 'boolean', 'nil'}) end local arr = {} local index = 1 for k in pairs(t) do arr[index] = k index = index + 1 end if keySort ~= false then keySort = type(keySort) == 'function' and keySort or defaultKeySort table.sort(arr, keySort) end return arr end ------------------------------------------------------------------------------------ -- sortedPairs -- -- Iterates through a table, with the keys sorted using the keysToList function. -- If there are only numerical keys, sparseIpairs is probably more efficient. ------------------------------------------------------------------------------------ function p.sortedPairs(t, keySort) checkType('sortedPairs', 1, t, 'table') checkType('sortedPairs', 2, keySort, 'function', true) local arr = p.keysToList(t, keySort, true) local i = 0 return function () i = i + 1 local key = arr[i] if key ~= nil then return key, t[key] else return nil, nil end end end ------------------------------------------------------------------------------------ -- isArray -- -- Returns true if the given value is a table and all keys are consecutive -- integers starting at 1. ------------------------------------------------------------------------------------ function p.isArray(v) if type(v) ~= 'table' then return false end local i = 0 for _ in pairs(v) do i = i + 1 if v[i] == nil then return false end end return true end ------------------------------------------------------------------------------------ -- isArrayLike -- -- Returns true if the given value is iterable and all keys are consecutive -- integers starting at 1. ------------------------------------------------------------------------------------ function p.isArrayLike(v) if not pcall(pairs, v) then return false end local i = 0 for _ in pairs(v) do i = i + 1 if v[i] == nil then return false end end return true end ------------------------------------------------------------------------------------ -- invert -- -- Transposes the keys and values in an array. For example, {"a", "b", "c"} -> -- {a = 1, b = 2, c = 3}. Duplicates are not supported (result values refer to -- the index of the last duplicate) and NaN values are ignored. ------------------------------------------------------------------------------------ function p.invert(arr) checkType("invert", 1, arr, "table") local isNan = p.isNan local map = {} for i, v in ipairs(arr) do if not isNan(v) then map[v] = i end end return map end ------------------------------------------------------------------------------------ -- listToSet -- -- Creates a set from the array part of the table. Indexing the set by any of the -- values of the array returns true. For example, {"a", "b", "c"} -> -- {a = true, b = true, c = true}. NaN values are ignored as Lua considers them -- never equal to any value (including other NaNs or even themselves). ------------------------------------------------------------------------------------ function p.listToSet(arr) checkType("listToSet", 1, arr, "table") local isNan = p.isNan local set = {} for _, v in ipairs(arr) do if not isNan(v) then set[v] = true end end return set end ------------------------------------------------------------------------------------ -- deepCopy -- -- Recursive deep copy function. Preserves identities of subtables. ------------------------------------------------------------------------------------ local function _deepCopy(orig, includeMetatable, already_seen) -- Stores copies of tables indexed by the original table. already_seen = already_seen or {} local copy = already_seen[orig] if copy ~= nil then return copy end if type(orig) == 'table' then copy = {} for orig_key, orig_value in pairs(orig) do copy[_deepCopy(orig_key, includeMetatable, already_seen)] = _deepCopy(orig_value, includeMetatable, already_seen) end already_seen[orig] = copy if includeMetatable then local mt = getmetatable(orig) if mt ~= nil then local mt_copy = _deepCopy(mt, includeMetatable, already_seen) setmetatable(copy, mt_copy) already_seen[mt] = mt_copy end end else -- number, string, boolean, etc copy = orig end return copy end function p.deepCopy(orig, noMetatable, already_seen) checkType("deepCopy", 3, already_seen, "table", true) return _deepCopy(orig, not noMetatable, already_seen) end ------------------------------------------------------------------------------------ -- sparseConcat -- -- Concatenates all values in the table that are indexed by a number, in order. -- sparseConcat{a, nil, c, d} => "acd" -- sparseConcat{nil, b, c, d} => "bcd" ------------------------------------------------------------------------------------ function p.sparseConcat(t, sep, i, j) local arr = {} local arr_i = 0 for _, v in p.sparseIpairs(t) do arr_i = arr_i + 1 arr[arr_i] = v end return table.concat(arr, sep, i, j) end ------------------------------------------------------------------------------------ -- length -- -- Finds the length of an array, or of a quasi-array with keys such as "data1", -- "data2", etc., using an exponential search algorithm. It is similar to the -- operator #, but may return a different value when there are gaps in the array -- portion of the table. Intended to be used on data loaded with mw.loadData. For -- other tables, use #. -- Note: #frame.args in frame object always be set to 0, regardless of the number -- of unnamed template parameters, so use this function for frame.args. ------------------------------------------------------------------------------------ function p.length(t, prefix) -- requiring module inline so that [[Module:Exponential search]] which is -- only needed by this one function doesn't get millions of transclusions local expSearch = require("Module:Exponential search") checkType('length', 1, t, 'table') checkType('length', 2, prefix, 'string', true) return expSearch(function (i) local key if prefix then key = prefix .. tostring(i) else key = i end return t[key] ~= nil end) or 0 end ------------------------------------------------------------------------------------ -- inArray -- -- Returns true if valueToFind is a member of the array, and false otherwise. ------------------------------------------------------------------------------------ function p.inArray(arr, valueToFind) checkType("inArray", 1, arr, "table") -- if valueToFind is nil, error? for _, v in ipairs(arr) do if v == valueToFind then return true end end return false end return p 085e7094ac84eb0132ee65822cf3f69cd8ba3d81 แม่แบบ:Unbulleted list 10 24 37 2023-10-05T10:58:41Z PeachFullzZ 2 สร้างหน้าด้วย "{{<includeonly>safesubst:</includeonly>#invoke:list|unbulleted}}<noinclude> {{documentation}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude>" wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:list|unbulleted}}<noinclude> {{documentation}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude> 89815a491d3e05b20af446e34cda13f13c25fb4f มอดูล:List 828 25 38 2023-10-05T10:59:37Z PeachFullzZ 2 สร้างหน้าด้วย "local libUtil = require('libraryUtil') local checkType = libUtil.checkType local mTableTools = require('Module:TableTools') local p = {} local listTypes = { ['bulleted'] = true, ['unbulleted'] = true, ['horizontal'] = true, ['ordered'] = true, ['horizontal_ordered'] = true } function p.makeListData(listType, args) -- Constructs a data table to be passed to p.renderList. local data = {} -- Classes and TemplateStyles data.classes = {} da..." Scribunto text/plain local libUtil = require('libraryUtil') local checkType = libUtil.checkType local mTableTools = require('Module:TableTools') local p = {} local listTypes = { ['bulleted'] = true, ['unbulleted'] = true, ['horizontal'] = true, ['ordered'] = true, ['horizontal_ordered'] = true } function p.makeListData(listType, args) -- Constructs a data table to be passed to p.renderList. local data = {} -- Classes and TemplateStyles data.classes = {} data.templatestyles = '' if listType == 'horizontal' or listType == 'horizontal_ordered' then table.insert(data.classes, 'hlist') data.templatestyles = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Hlist/styles.css' } } elseif listType == 'unbulleted' then table.insert(data.classes, 'plainlist') data.templatestyles = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Plainlist/styles.css' } } end table.insert(data.classes, args.class) -- Main div style data.style = args.style -- Indent for horizontal lists if listType == 'horizontal' or listType == 'horizontal_ordered' then local indent = tonumber(args.indent) indent = indent and indent * 1.6 or 0 if indent > 0 then data.marginLeft = indent .. 'em' end end -- List style types for ordered lists -- This could be "1, 2, 3", "a, b, c", or a number of others. The list style -- type is either set by the "type" attribute or the "list-style-type" CSS -- property. if listType == 'ordered' or listType == 'horizontal_ordered' then data.listStyleType = args.list_style_type or args['list-style-type'] data.type = args['type'] -- Detect invalid type attributes and attempt to convert them to -- list-style-type CSS properties. if data.type and not data.listStyleType and not tostring(data.type):find('^%s*[1AaIi]%s*$') then data.listStyleType = data.type data.type = nil end end -- List tag type if listType == 'ordered' or listType == 'horizontal_ordered' then data.listTag = 'ol' else data.listTag = 'ul' end -- Start number for ordered lists data.start = args.start if listType == 'horizontal_ordered' then -- Apply fix to get start numbers working with horizontal ordered lists. local startNum = tonumber(data.start) if startNum then data.counterReset = 'listitem ' .. tostring(startNum - 1) end end -- List style -- ul_style and ol_style are included for backwards compatibility. No -- distinction is made for ordered or unordered lists. data.listStyle = args.list_style -- List items -- li_style is included for backwards compatibility. item_style was included -- to be easier to understand for non-coders. data.itemStyle = args.item_style or args.li_style data.items = {} for _, num in ipairs(mTableTools.numKeys(args)) do local item = {} item.content = args[num] item.style = args['item' .. tostring(num) .. '_style'] or args['item_style' .. tostring(num)] item.value = args['item' .. tostring(num) .. '_value'] or args['item_value' .. tostring(num)] table.insert(data.items, item) end return data end function p.renderList(data) -- Renders the list HTML. -- Return the blank string if there are no list items. if type(data.items) ~= 'table' or #data.items < 1 then return '' end -- Render the main div tag. local root = mw.html.create('div') for _, class in ipairs(data.classes or {}) do root:addClass(class) end root:css{['margin-left'] = data.marginLeft} if data.style then root:cssText(data.style) end -- Render the list tag. local list = root:tag(data.listTag or 'ul') list :attr{start = data.start, type = data.type} :css{ ['counter-reset'] = data.counterReset, ['list-style-type'] = data.listStyleType } if data.listStyle then list:cssText(data.listStyle) end -- Render the list items for _, t in ipairs(data.items or {}) do local item = list:tag('li') if data.itemStyle then item:cssText(data.itemStyle) end if t.style then item:cssText(t.style) end item :attr{value = t.value} :wikitext(t.content) end return data.templatestyles .. tostring(root) end function p.renderTrackingCategories(args) local isDeprecated = false -- Tracks deprecated parameters. for k, v in pairs(args) do k = tostring(k) if k:find('^item_style%d+$') or k:find('^item_value%d+$') then isDeprecated = true break end end local ret = '' if isDeprecated then ret = ret .. '[[Category:List templates with deprecated parameters]]' end return ret end function p.makeList(listType, args) if not listType or not listTypes[listType] then error(string.format( "bad argument #1 to 'makeList' ('%s' is not a valid list type)", tostring(listType) ), 2) end checkType('makeList', 2, args, 'table') local data = p.makeListData(listType, args) local list = p.renderList(data) local trackingCategories = p.renderTrackingCategories(args) return list .. trackingCategories end for listType in pairs(listTypes) do p[listType] = function (frame) local mArguments = require('Module:Arguments') local origArgs = mArguments.getArgs(frame, { valueFunc = function (key, value) if not value or not mw.ustring.find(value, '%S') then return nil end if mw.ustring.find(value, '^%s*[%*#;:]') then return value else return value:match('^%s*(.-)%s*$') end return nil end }) -- Copy all the arguments to a new table, for faster indexing. local args = {} for k, v in pairs(origArgs) do args[k] = v end return p.makeList(listType, args) end end return p 7a4f36a6e9cd56370bdd8207d23694124821dc1a แม่แบบ:Str rep 10 26 41 2023-10-05T11:16:56Z PeachFullzZ 2 สร้างหน้าด้วย "{{#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|1}}<noinclude> {{Documentation}}</noinclude>" wikitext text/x-wiki {{#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|1}}<noinclude> {{Documentation}}</noinclude> 4706daa3137857f2792cc7109ca24b6d58c78dee 42 41 2023-10-05T11:17:32Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Str rep]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki {{#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|1}}<noinclude> {{Documentation}}</noinclude> 4706daa3137857f2792cc7109ca24b6d58c78dee แม่แบบ:En dash range 10 27 43 2023-10-05T11:18:19Z PeachFullzZ 2 สร้างหน้าด้วย "{{{1}}}{{#ifeq:{{#invoke:String|find|source={{#invoke:Plain text|main|{{{1}}}{{{2}}}}}|target=[%s–—-]|plain=false}}|0|–|&nbsp;–&#32;}}{{{2}}}<noinclude> {{Documentation}} </noinclude>" wikitext text/x-wiki {{{1}}}{{#ifeq:{{#invoke:String|find|source={{#invoke:Plain text|main|{{{1}}}{{{2}}}}}|target=[%s–—-]|plain=false}}|0|–|&nbsp;–&#32;}}{{{2}}}<noinclude> {{Documentation}} </noinclude> 4f0bde90a2efc3a10317f528ce19b0e0fd212808 44 43 2023-10-05T11:18:34Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:En dash range]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki {{{1}}}{{#ifeq:{{#invoke:String|find|source={{#invoke:Plain text|main|{{{1}}}{{{2}}}}}|target=[%s–—-]|plain=false}}|0|–|&nbsp;–&#32;}}{{{2}}}<noinclude> {{Documentation}} </noinclude> 4f0bde90a2efc3a10317f528ce19b0e0fd212808 มอดูล:If preview 828 28 49 2023-10-05T11:37:34Z PeachFullzZ 2 สร้างหน้าด้วย "local p = {} local cfg = mw.loadData('Module:If preview/configuration') --[[ main This function returns either the first argument or second argument passed to this module, depending on whether the page is being previewed. ]] function p.main(frame) if cfg.preview then return frame.args[1] or '' else return frame.args[2] or '' end end --[[ pmain This function returns either the first argument or second argument passed to this module's par..." Scribunto text/plain local p = {} local cfg = mw.loadData('Module:If preview/configuration') --[[ main This function returns either the first argument or second argument passed to this module, depending on whether the page is being previewed. ]] function p.main(frame) if cfg.preview then return frame.args[1] or '' else return frame.args[2] or '' end end --[[ pmain This function returns either the first argument or second argument passed to this module's parent (i.e. template using this module), depending on whether it is being previewed. ]] function p.pmain(frame) return p.main(frame:getParent()) end local function warning_text(warning) return mw.ustring.format( cfg.warning_infrastructure, cfg.templatestyles, warning ) end function p._warning(args) local warning = args[1] and args[1]:match('^%s*(.-)%s*$') or '' if warning == '' then return warning_text(cfg.missing_warning) end if not cfg.preview then return '' end return warning_text(warning) end --[[ warning This function returns a "preview warning", which is the first argument marked up with HTML and some supporting text, depending on whether the page is being previewed. disabled since we'll implement the template version in general ]] --function p.warning(frame) -- return p._warning(frame.args) --end --[[ warning, but for pass-through templates like {{preview warning}} ]] function p.pwarning(frame) return p._warning(frame:getParent().args) end return p 9a92196d0001b8016f2501aedfadcc3adcb974ef 50 49 2023-10-05T11:37:50Z PeachFullzZ 2 ป้องกัน "[[มอดูล:If preview]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local p = {} local cfg = mw.loadData('Module:If preview/configuration') --[[ main This function returns either the first argument or second argument passed to this module, depending on whether the page is being previewed. ]] function p.main(frame) if cfg.preview then return frame.args[1] or '' else return frame.args[2] or '' end end --[[ pmain This function returns either the first argument or second argument passed to this module's parent (i.e. template using this module), depending on whether it is being previewed. ]] function p.pmain(frame) return p.main(frame:getParent()) end local function warning_text(warning) return mw.ustring.format( cfg.warning_infrastructure, cfg.templatestyles, warning ) end function p._warning(args) local warning = args[1] and args[1]:match('^%s*(.-)%s*$') or '' if warning == '' then return warning_text(cfg.missing_warning) end if not cfg.preview then return '' end return warning_text(warning) end --[[ warning This function returns a "preview warning", which is the first argument marked up with HTML and some supporting text, depending on whether the page is being previewed. disabled since we'll implement the template version in general ]] --function p.warning(frame) -- return p._warning(frame.args) --end --[[ warning, but for pass-through templates like {{preview warning}} ]] function p.pwarning(frame) return p._warning(frame:getParent().args) end return p 9a92196d0001b8016f2501aedfadcc3adcb974ef แม่แบบ:Main other 10 29 51 2023-10-05T11:39:15Z PeachFullzZ 2 สร้างหน้าด้วย "{{#switch: <!--If no or empty "demospace" parameter then detect namespace--> {{#if:{{{demospace|}}} | {{lc: {{{demospace}}} }} <!--Use lower case "demospace"--> | {{#ifeq:{{NAMESPACE}}|{{ns:0}} | main | other }} }} | main = {{{1|}}} | other | #default = {{{2|}}} }}<noinclude> {{documentation}} <!-- Add categories to the /doc subpage; interwikis go to Wikidata, thank you! --> </noinclude>" wikitext text/x-wiki {{#switch: <!--If no or empty "demospace" parameter then detect namespace--> {{#if:{{{demospace|}}} | {{lc: {{{demospace}}} }} <!--Use lower case "demospace"--> | {{#ifeq:{{NAMESPACE}}|{{ns:0}} | main | other }} }} | main = {{{1|}}} | other | #default = {{{2|}}} }}<noinclude> {{documentation}} <!-- Add categories to the /doc subpage; interwikis go to Wikidata, thank you! --> </noinclude> 86ad907ffeea3cc545159e00cd1f2d6433946450 แม่แบบ:Main other 10 29 52 51 2023-10-05T11:39:37Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Main other]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki {{#switch: <!--If no or empty "demospace" parameter then detect namespace--> {{#if:{{{demospace|}}} | {{lc: {{{demospace}}} }} <!--Use lower case "demospace"--> | {{#ifeq:{{NAMESPACE}}|{{ns:0}} | main | other }} }} | main = {{{1|}}} | other | #default = {{{2|}}} }}<noinclude> {{documentation}} <!-- Add categories to the /doc subpage; interwikis go to Wikidata, thank you! --> </noinclude> 86ad907ffeea3cc545159e00cd1f2d6433946450 แม่แบบ:NAMESPACE 10 30 53 2023-10-05T11:42:59Z PeachFullzZ 2 เปลี่ยนทางหน้าไปยัง [[แม่แบบ:Namespace]] wikitext text/x-wiki #เปลี่ยนทาง[[แม่แบบ:Namespace]] 2822878c926055331098c96e1f848eaf5d8a65d5 แม่แบบ:Namespace 10 31 54 2023-10-05T11:43:30Z PeachFullzZ 2 สร้างหน้าด้วย "{{NAMESPACE:{{{1|}}}}}<includeonly>[[Category:Pages which use a template in place of a magic word|E{{PAGENAME}}]]</includeonly><noinclude> {{Documentation}}</noinclude>" wikitext text/x-wiki {{NAMESPACE:{{{1|}}}}}<includeonly>[[Category:Pages which use a template in place of a magic word|E{{PAGENAME}}]]</includeonly><noinclude> {{Documentation}}</noinclude> 3c1ea0505b651f9731cbae05f2c3e38b92210582 ไฟล์:Anavin Sukkasem-Adisak (2 August 2023).png 6 33 56 2023-10-05T11:52:45Z PeachFullzZ 2 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 มอดูล:If preview/configuration 828 34 57 2023-10-05T12:14:13Z PeachFullzZ 2 สร้างหน้าด้วย "--[[ We perform the actual check for whether this is a preview here since preprocessing is relatively expensive. ]] local frame = mw.getCurrentFrame() local function is_preview() local revision_id = frame:preprocess('{{REVISIONID}}') -- {{REVISIONID}} is usually the empty string when previewed. -- I don't know why we're checking for nil but hey, maybe someday things -- would have broken return revision_id == nil or revision_id == '' end local..." Scribunto text/plain --[[ We perform the actual check for whether this is a preview here since preprocessing is relatively expensive. ]] local frame = mw.getCurrentFrame() local function is_preview() local revision_id = frame:preprocess('{{REVISIONID}}') -- {{REVISIONID}} is usually the empty string when previewed. -- I don't know why we're checking for nil but hey, maybe someday things -- would have broken return revision_id == nil or revision_id == '' end local function templatestyles() return frame:extensionTag{ name = 'templatestyles', args = { src = 'Module:If preview/styles.css' } } end return { preview = is_preview(), templatestyles = templatestyles(), warning_infrastructure = '%s<div class="preview-warning"><strong>Preview warning:</strong> %s</div>', missing_warning = 'The template has no warning text. Please add a warning.' } 3edc8897c51a61b9e710b2a4d9eb657b3c2f1034 58 57 2023-10-05T12:14:32Z PeachFullzZ 2 ป้องกัน "[[มอดูล:If preview/configuration]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain --[[ We perform the actual check for whether this is a preview here since preprocessing is relatively expensive. ]] local frame = mw.getCurrentFrame() local function is_preview() local revision_id = frame:preprocess('{{REVISIONID}}') -- {{REVISIONID}} is usually the empty string when previewed. -- I don't know why we're checking for nil but hey, maybe someday things -- would have broken return revision_id == nil or revision_id == '' end local function templatestyles() return frame:extensionTag{ name = 'templatestyles', args = { src = 'Module:If preview/styles.css' } } end return { preview = is_preview(), templatestyles = templatestyles(), warning_infrastructure = '%s<div class="preview-warning"><strong>Preview warning:</strong> %s</div>', missing_warning = 'The template has no warning text. Please add a warning.' } 3edc8897c51a61b9e710b2a4d9eb657b3c2f1034 แม่แบบ:กล่องข้อมูล ผู้ดำรงตำแหน่ง 10 11 59 47 2023-10-05T12:20:09Z PeachFullzZ 2 wikitext text/x-wiki {{#invoke:infobox|infoboxTemplate | bodyclass = vcard {{{bodyclass|}}} | bodystyle = {{#if:{{{mainwidth|}}}|width: {{{mainwidth}}}}} | child = {{lc:{{{embed}}}}} | abovestyle = font-size: 100%; | above = {{#if:{{{honorific prefix|{{{honorific_prefix|{{{honorific-prefix|}}}}}}}}}|<div class="honorific-prefix" style="font-weight: normal;">{{{honorific prefix|{{{honorific_prefix|{{{honorific-prefix}}}}}}}}}</div>}}<!-- --><div class="fn" style="font-size:125%;">{{#if:{{{name|}}}|{{{name}}}|{{PAGENAMEBASE}}}}</div><!-- -->{{#if:{{{honorific suffix|{{{honorific_suffix|{{{honorific-suffix|}}}}}}}}}|<div class="honorific-suffix" style="font-weight: normal;">{{{honorific suffix|{{{honorific_suffix|{{{honorific-suffix}}}}}}}}}</div>}} | subheaderstyle = font-size:125%; font-weight:bold; | subheader = {{#ifeq:{{lc:{{{embed}}}}}|yes||(@{{#if:{{{roblox_username|}}}|{{{roblox_username}}}}})}} | image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{{width|{{{imagesize|{{{image_size|}}}}}}}}}|sizedefault=frameless|upright={{{image_upright|1}}}|alt={{{alt|}}}|suppressplaceholder=yes}} | image2 = {{#invoke:InfoboxImage|InfoboxImage|image={{{image name|}}}|size={{{width|{{{imagesize|{{{image_size|}}}}}}}}}|sizedefault=frameless|upright={{{image_upright|1}}}|alt={{{image_name_alt|}}}|suppressplaceholder=yes}} | image3 = {{#invoke:InfoboxImage|InfoboxImage|image={{{smallimage|}}}|sizedefault=frameless|upright={{{image_upright|1}}}|alt={{{smallimage_alt|}}}|suppressplaceholder=yes}} | captionstyle = line-height:normal;padding-top:0.2em; | caption{{#if:{{{smallimage|}}}|3|{{#if:{{{image name|}}}|2}}}} = {{{caption|}}} | headerstyle = {{#ifeq:{{lc:{{{embed}}}}}|yes|background:#eee|background:lavender}} | data1 = {{#if:{{{speaker|}}}| {{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname2|}}} | 1namedata = {{{1namedata2|}}} | 2blankname = {{{2blankname2|}}} | 2namedata = {{{2namedata2|}}} | 3blankname = {{{3blankname2|}}} | 3namedata = {{{3namedata2|}}} | 4blankname = {{{4blankname2|}}} | 4namedata = {{{4namedata2|}}} | 5blankname = {{{5blankname2|}}} | 5namedata = {{{5namedata2|}}} | alongside = {{{alongside2|}}} | ambassador_from = {{{ambassador_from2|}}} | appointer = {{#if: {{{appointer2|}}} | {{{appointer2}}} | {{{appointed2|}}} }} | assembly = {{{assembly2|}}} | assuming = {{{assuming2|}}} | chancellor = {{{chancellor2|}}} | co-leader = {{{co-leader2|}}} | constituency_{{#if:{{{constituency_AM2|}}}|AM|MP}} = {{#if: {{{constituency_AM2|}}} | {{{constituency_AM2}}} | {{{constituency_MP2|}}} }} | constituency = {{{constituency2|}}} | convocation = {{{convocation2|}}} | country = {{{country2|}}} | deputy = {{{deputy2|}}} | deputyminister = {{{deputyminister2|}}} | headminister = {{{headminister2|}}} | district = {{{district2|}}} | firstminister = {{{firstminister2|}}} | governor-general = {{{governor-general2|}}} | governor_general = {{{governor_general2|}}} | governor = {{{governor2|}}} | jr/sr = {{{jr/sr2|}}} | jr/sr and state = {{{jr/sr and state2|}}} | leader = {{{leader2|}}} | legislature = {{{legislature2|}}} | lieutenant_governor = {{{lieutenant_governor2|}}} | lieutenant = {{{lieutenant2|}}} | majority_leader = {{#if: {{{majorityleader2|}}} | {{{majorityleader2}}} | {{{majority_leader2|}}} }} | minister_from = {{{minister_from2|}}} | minority_floor_leader = {{{minority_floor_leader2|}}} | majority_floor_leader = {{{majority_floor_leader2|}}} | majority = {{{majority2|}}} | minister = {{{minister2|}}} | minority_leader = {{#if: {{{minorityleader2|}}} | {{{minorityleader2}}} | {{{minority_leader2|}}} }} | monarch = {{{monarch2|}}} | nominator = {{{nominator2|}}} | office = {{{office2|}}} | order = {{{order2|}}} | parliament = {{{parliament2|}}} | parliamentarygroup = {{{parliamentarygroup2|}}} | predecessor = {{{predecessor2|}}} | preceding = {{{preceding2|}}} | preceded = {{{preceded2|}}} | premier = {{{premier2|}}} | president = {{{president2|}}} | primeminister = {{{primeminister2|}}} | riding = {{{riding2|}}} | speaker = {{{speaker|}}} | speaker_office = {{{speaker_office|}}} | state_assembly = {{{state_assembly|}}} | state_delegate = {{{state_delegate|}}} | state_house = {{{state_house|}}} | state_legislature = {{{state_legislature|}}} | state_senate = {{{state_senate|}}} | state = {{{state|}}} | subterm = {{{subterm|}}} | suboffice = {{{suboffice|}}} | succeeded = {{{succeeded2|}}} | succeeding = {{{succeeding2|}}} | successor = {{{successor2|}}} | taoiseach = {{{taoiseach2|}}} | termlabel = {{{term_label2|{{{termlabel2|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend2|}}}|{{{termend2}}}|{{{term_end2|}}}}} | termstart = {{#if:{{{termstart2|}}}|{{{termstart2}}}|{{{term_start2|}}}}} | term = {{{term2|}}} | title = {{{title2|}}} | vicegovernor = {{{vicegovernor2|}}} | vicepresident = {{{vicepresident2|}}} | vicepremier = {{{vicepremier2|}}} | viceprimeminister = {{{viceprimeminister2|}}} | party = {{{party|}}} | prior_term = {{{prior_term|}}} }}}}}}<!-- -->{{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname|}}} | 1namedata = {{{1namedata|}}} | 2blankname = {{{2blankname|}}} | 2namedata = {{{2namedata|}}} | 3blankname = {{{3blankname|}}} | 3namedata = {{{3namedata|}}} | 4blankname = {{{4blankname|}}} | 4namedata = {{{4namedata|}}} | 5blankname = {{{5blankname|}}} | 5namedata = {{{5namedata|}}} | alongside = {{{alongside|}}} | ambassador_from = {{{ambassador_from|}}} | appointer = {{#if: {{{appointer|}}} | {{{appointer}}} | {{{appointed|}}} }} | assembly = {{{assembly|}}} | assuming = {{{assuming|}}} | candidate = {{{candidate|}}} | chancellor = {{{chancellor|}}} | co-leader = {{{co-leader|}}} | constituency_{{#if:{{{constituency_AM|}}}|AM|MP}} = {{#if: {{{constituency_AM|}}} | {{{constituency_AM}}} | {{{constituency_MP|}}} }} | constituency = {{{constituency|}}} | convocation = {{{convocation|}}} | country = {{{country|}}} | deputy = {{{deputy|}}} | deputyminister = {{{deputyminister|}}} | headminister = {{{headminister|}}} | district = {{{district|}}} | election_date = {{{election_date|}}} | firstminister = {{{firstminister|}}} | governor-general = {{{governor-general|}}} | governor_general = {{{governor_general|}}} | governor = {{{governor|}}} | incumbent = {{{incumbent|}}} | jr/sr = {{{jr/sr|}}} | jr/sr and state = {{{jr/sr and state|}}} | leader = {{{leader|}}} | legislature = {{{legislature|}}} | lieutenant_governor = {{{lieutenant_governor|}}} | lieutenant = {{{lieutenant|}}} | majority_leader = {{#if: {{{majorityleader|}}} | {{{majorityleader}}} | {{{majority_leader|}}} }} | majority = {{{majority|}}} | minister = {{{minister|}}} | minister_from = {{{minister_from|}}} | minority_floor_leader = {{{minority_floor_leader|}}} | majority_floor_leader = {{{majority_floor_leader|}}} | minority_leader = {{#if: {{{minorityleader|}}} | {{{minorityleader}}} | {{{minority_leader|}}} }} | monarch = {{{monarch|}}} | nominator = {{{nominator|}}} | nominee = {{{nominee|}}} | office = {{{office|}}} | opponent = {{{opponent|}}} | order = {{{order|}}} | parliament = {{{parliament|}}} | parliamentarygroup = {{{parliamentarygroup|}}} | party_election = {{{party_election|}}} | predecessor = {{{predecessor|}}} | preceding = {{{preceding|}}} | preceded = {{{preceded|}}} | premier = {{{premier|}}} | president = {{{president|}}} | primeminister = {{{primeminister|}}} | riding = {{{riding|}}} | runningmate = {{{runningmate|}}} | state_assembly = {{{state_assembly|}}} | state_delegate = {{{state_delegate|}}} | state_house = {{{state_house|}}} | state_legislature = {{{state_legislature|}}} | state_senate = {{{state_senate|}}} | state = {{{state|}}} | status = {{{status|}}} | suboffice = {{{suboffice|}}} | subterm = {{{subterm|}}} | succeeded = {{{succeeded|}}} | succeeding = {{{succeeding|}}} | successor = {{{successor|}}} | taoiseach = {{{taoiseach|}}} | termlabel = {{{term_label|{{{termlabel|ดำรงตำแหน่ง}}}}}} | termend = {{#if: {{{termend|}}} | {{{termend}}} | {{{term_end|}}} }} | termstart = {{#if: {{{termstart|}}} | {{{termstart}}} | {{{term_start|}}} }} | term = {{{term|}}} | title = {{{title|}}} | vicegovernor = {{{vicegovernor|}}} | vicepresident = {{{vicepresident|}}} | vicepremier = {{{vicepremier|}}} | viceprimeminister = {{{viceprimeminister|}}} | party = {{{party|}}} | prior_term = {{{prior_term|}}} }}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname1|}}} | 1namedata = {{{1namedata1|}}} | 2blankname = {{{2blankname1|}}} | 2namedata = {{{2namedata1|}}} | 3blankname = {{{3blankname1|}}} | 3namedata = {{{3namedata1|}}} | 4blankname = {{{4blankname1|}}} | 4namedata = {{{4namedata1|}}} | 5blankname = {{{5blankname1|}}} | 5namedata = {{{5namedata1|}}} | alongside = {{{alongside1|}}} | ambassador_from = {{{ambassador_from1|}}} | appointer = {{#if: {{{appointer1|}}} | {{{appointer1}}} | {{{appointed1|}}} }} | assembly = {{{assembly1|}}} | assuming = {{{assuming1|}}} | chancellor = {{{chancellor1|}}} | co-leader = {{{co-leader1|}}} | constituency_{{#if:{{{constituency_AM1|}}}|AM|MP}} = {{#if: {{{constituency_AM1|}}} | {{{constituency_AM1}}} | {{{constituency_MP1|}}} }} | constituency = {{{constituency1|}}} | convocation = {{{convocation1|}}} | country = {{{country1|}}} | deputy = {{{deputy1|}}} | deputyminister = {{{deputyminister1|}}} | headminister = {{{headminister1|}}} | district = {{{district1|}}} | firstminister = {{{firstminister1|}}} | governor-general = {{{governor-general1|}}} | governor_general = {{{governor_general1|}}} | governor = {{{governor1|}}} | jr/sr = {{{jr/sr1|}}} | jr/sr and state = {{{jr/sr and state1|}}} | leader = {{{leader1|}}} | legislature = {{{legislature1|}}} | lieutenant_governor = {{{lieutenant_governor1|}}} | lieutenant = {{{lieutenant1|}}} | minority_floor_leader = {{{minority_floor_leader1|}}} | minister_from = {{{minister_from1|}}} | majority_floor_leader = {{{majority_floor_leader1|}}} | majority_leader = {{#if: {{{majorityleader1|}}} | {{{majorityleader1}}} | {{{majority_leader1|}}} }} | majority = {{{majority1|}}} | minister = {{{minister1|}}} | minority_leader = {{#if: {{{minorityleader1|}}} | {{{minorityleader1}}} | {{{minority_leader1|}}} }} | monarch = {{{monarch1|}}} | nominator = {{{nominator1|}}} | office = {{{office1|}}} | order = {{{order1|}}} | parliament = {{{parliament1|}}} | parliamentarygroup = {{{parliamentarygroup1|}}} | predecessor = {{{predecessor1|}}} | preceding = {{{preceding1|}}} | preceded = {{{preceded1|}}} | premier = {{{premier1|}}} | president = {{{president1|}}} | primeminister = {{{primeminister1|}}} | riding = {{{riding1|}}} | state_assembly = {{{state_assembly1|}}} | state_delegate = {{{state_delegate1|}}} | state_house = {{{state_house1|}}} | state_legislature = {{{state_legislature1|}}} | state_senate = {{{state_senate1|}}} | state = {{{state1|}}} | status = {{{status1|}}} | subterm = {{{subterm1|}}} | suboffice = {{{suboffice1|}}} | succeeded = {{{succeeded1|}}} | succeeding = {{{succeeding1|}}} | successor = {{{successor1|}}} | taoiseach = {{{taoiseach1|}}} | termlabel = {{{term_label1|{{{termlabel1|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend1|}}}|{{{termend1}}}|{{{term_end1|}}}}} | termstart = {{#if:{{{termstart1|}}}|{{{termstart1}}}|{{{term_start1|}}}}} | term = {{{term1|}}} | title = {{{title1|}}} | vicegovernor = {{{vicegovernor1|}}} | vicepresident = {{{vicepresident1|}}} | vicepremier = {{{vicepremier1|}}} | viceprimeminister = {{{viceprimeminister1|}}} | party = {{{party|}}} | prior_term = {{{prior_term1|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{#if:{{{speaker|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname2|}}} | 1namedata = {{{1namedata2|}}} | 2blankname = {{{2blankname2|}}} | 2namedata = {{{2namedata2|}}} | 3blankname = {{{3blankname2|}}} | 3namedata = {{{3namedata2|}}} | 4blankname = {{{4blankname2|}}} | 4namedata = {{{4namedata2|}}} | 5blankname = {{{5blankname2|}}} | 5namedata = {{{5namedata2|}}} | alongside = {{{alongside2|}}} | ambassador_from = {{{ambassador_from2|}}} | appointer = {{#if: {{{appointer2|}}} | {{{appointer2}}} | {{{appointed2|}}} }} | assembly = {{{assembly2|}}} | assuming = {{{assuming2|}}} | chancellor = {{{chancellor2|}}} | co-leader = {{{co-leader2|}}} | constituency_{{#if:{{{constituency_AM2|}}}|AM|MP}} = {{#if: {{{constituency_AM2|}}} | {{{constituency_AM2}}} | {{{constituency_MP2|}}} }} | constituency = {{{constituency2|}}} | convocation = {{{convocation2|}}} | country = {{{country2|}}} | deputy = {{{deputy2|}}} | deputyminister = {{{deputyminister2|}}} | headminister = {{{headminister2|}}} | district = {{{district2|}}} | firstminister = {{{firstminister2|}}} | governor-general = {{{governor-general2|}}} | governor_general = {{{governor_general2|}}} | governor = {{{governor2|}}} | jr/sr = {{{jr/sr2|}}} | jr/sr and state = {{{jr/sr and state2|}}} | leader = {{{leader2|}}} | legislature = {{{legislature2|}}} | lieutenant_governor = {{{lieutenant_governor2|}}} | lieutenant = {{{lieutenant2|}}} | majority_leader = {{#if: {{{majorityleader2|}}} | {{{majorityleader2}}} | {{{majority_leader2|}}} }} | minister_from = {{{minister_from2|}}} | minority_floor_leader = {{{minority_floor_leader2|}}} | majority_floor_leader = {{{majority_floor_leader2|}}} | majority = {{{majority2|}}} | minister = {{{minister2|}}} | minority_leader = {{#if: {{{minorityleader2|}}} | {{{minorityleader2}}} | {{{minority_leader2|}}} }} | monarch = {{{monarch2|}}} | nominator = {{{nominator2|}}} | office = {{{office2|}}} | order = {{{order2|}}} | parliament = {{{parliament2|}}} | parliamentarygroup = {{{parliamentarygroup2|}}} | predecessor = {{{predecessor2|}}} | preceding = {{{preceding2|}}} | preceded = {{{preceded2|}}} | premier = {{{premier2|}}} | president = {{{president2|}}} | primeminister = {{{primeminister2|}}} | riding = {{{riding2|}}} | state_assembly = {{{state_assembly2|}}} | state_delegate = {{{state_delegate2|}}} | state_house = {{{state_house2|}}} | state_legislature = {{{state_legislature2|}}} | state_senate = {{{state_senate2|}}} | state = {{{state2|}}} | status = {{{status2|}}} | subterm = {{{subterm2|}}} | suboffice = {{{suboffice2|}}} | succeeded = {{{succeeded2|}}} | succeeding = {{{succeeding2|}}} | successor = {{{successor2|}}} | taoiseach = {{{taoiseach2|}}} | termlabel = {{{term_label2|{{{termlabel2|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend2|}}}|{{{termend2}}}|{{{term_end2|}}}}} | termstart = {{#if:{{{termstart2|}}}|{{{termstart2}}}|{{{term_start2|}}}}} | term = {{{term2|}}} | title = {{{title2|}}} | vicegovernor = {{{vicegovernor2|}}} | vicepresident = {{{vicepresident2|}}} | vicepremier = {{{vicepremier2|}}} | viceprimeminister = {{{viceprimeminister2|}}} | party = {{{party|}}} | prior_term = {{{prior_term2|}}} }}}}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname3|}}} | 1namedata = {{{1namedata3|}}} | 2blankname = {{{2blankname3|}}} | 2namedata = {{{2namedata3|}}} | 3blankname = {{{3blankname3|}}} | 3namedata = {{{3namedata3|}}} | 4blankname = {{{4blankname3|}}} | 4namedata = {{{4namedata3|}}} | 5blankname = {{{5blankname3|}}} | 5namedata = {{{5namedata3|}}} | alongside = {{{alongside3|}}} | ambassador_from = {{{ambassador_from3|}}} | appointer = {{#if: {{{appointer3|}}} | {{{appointer3}}} | {{{appointed3|}}} }} | assembly = {{{assembly3|}}} | assuming = {{{assuming3|}}} | chancellor = {{{chancellor3|}}} | co-leader = {{{co-leader3|}}} | constituency_{{#if:{{{constituency_AM3|}}}|AM|MP}} = {{#if: {{{constituency_AM3|}}} | {{{constituency_AM3}}} | {{{constituency_MP3|}}} }} | constituency = {{{constituency3|}}} | convocation = {{{convocation3|}}} | country = {{{country3|}}} | deputy = {{{deputy3|}}} | deputyminister = {{{deputyminister3|}}} | headminister = {{{headminister3|}}} | district = {{{district3|}}} | firstminister = {{{firstminister3|}}} | governor-general = {{{governor-general3|}}} | governor_general = {{{governor_general3|}}} | governor = {{{governor3|}}} | jr/sr = {{{jr/sr3|}}} | jr/sr and state = {{{jr/sr and state3|}}} | leader = {{{leader3|}}} | legislature = {{{legislature3|}}} | lieutenant_governor = {{{lieutenant_governor3|}}} | lieutenant = {{{lieutenant3|}}} | minority_floor_leader = {{{minority_floor_leader3|}}} | minister_from = {{{minister_from3|}}} | majority_floor_leader = {{{majority_floor_leader3|}}} | majority_leader = {{#if: {{{majorityleader3|}}} | {{{majorityleader3}}} | {{{majority_leader3|}}} }} | majority = {{{majority3|}}} | minister = {{{minister3|}}} | minority_leader = {{#if: {{{minorityleader3|}}} | {{{minorityleader3}}} | {{{minority_leader3|}}} }} | monarch = {{{monarch3|}}} | nominator = {{{nominator3|}}} | office = {{{office3|}}} | order = {{{order3|}}} | parliament = {{{parliament3|}}} | parliamentarygroup = {{{parliamentarygroup3|}}} | predecessor = {{{predecessor3|}}} | preceding = {{{preceding3|}}} | preceded = {{{preceded3|}}} | premier = {{{premier3|}}} | president = {{{president3|}}} | primeminister = {{{primeminister3|}}} | riding = {{{riding3|}}} | state_assembly = {{{state_assembly3|}}} | state_delegate = {{{state_delegate3|}}} | state_house = {{{state_house3|}}} | state_legislature = {{{state_legislature3|}}} | state_senate = {{{state_senate3|}}} | state = {{{state3|}}} | status = {{{status3|}}} | subterm = {{{subterm3|}}} | suboffice = {{{suboffice3|}}} | succeeded = {{{succeeded3|}}} | succeeding = {{{succeeding3|}}} | successor = {{{successor3|}}} | taoiseach = {{{taoiseach3|}}} | termlabel = {{{term_label3|{{{termlabel3|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend3|}}}|{{{termend3}}}|{{{term_end3|}}}}} | termstart = {{#if:{{{termstart3|}}}|{{{termstart3}}}|{{{term_start3|}}}}} | term = {{{term3|}}} | title = {{{title3|}}} | vicegovernor = {{{vicegovernor3|}}} | vicepresident = {{{vicepresident3|}}} | vicepremier = {{{vicepremier3|}}} | viceprimeminister = {{{viceprimeminister3|}}} | party = {{{party|}}} | prior_term = {{{prior_term3|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname4|}}} | 1namedata = {{{1namedata4|}}} | 2blankname = {{{2blankname4|}}} | 2namedata = {{{2namedata4|}}} | 3blankname = {{{3blankname4|}}} | 3namedata = {{{3namedata4|}}} | 4blankname = {{{4blankname4|}}} | 4namedata = {{{4namedata4|}}} | 5blankname = {{{5blankname4|}}} | 5namedata = {{{5namedata4|}}} | alongside = {{{alongside4|}}} | ambassador_from = {{{ambassador_from4|}}} | appointer = {{#if: {{{appointer4|}}} | {{{appointer4}}} | {{{appointed4|}}} }} | assembly = {{{assembly4|}}} | assuming = {{{assuming4|}}} | chancellor = {{{chancellor4|}}} | co-leader = {{{co-leader4|}}} | constituency_{{#if:{{{constituency_AM4|}}}|AM|MP}} = {{#if: {{{constituency_AM4|}}} | {{{constituency_AM4}}} | {{{constituency_MP4|}}} }} | constituency = {{{constituency4|}}} | convocation = {{{convocation4|}}} | country = {{{country4|}}} | deputy = {{{deputy4|}}} | deputyminister = {{{deputyminister4|}}} | headminister = {{{headminister4|}}} | district = {{{district4|}}} | firstminister = {{{firstminister4|}}} | governor-general = {{{governor-general4|}}} | governor_general = {{{governor_general4|}}} | governor = {{{governor4|}}} | jr/sr = {{{jr/sr4|}}} | jr/sr and state = {{{jr/sr and state4|}}} | leader = {{{leader4|}}} | legislature = {{{legislature4|}}} | lieutenant_governor = {{{lieutenant_governor4|}}} | lieutenant = {{{lieutenant4|}}} | minister_from = {{{minister_from4|}}} | minority_floor_leader = {{{minority_floor_leader4|}}} | majority_floor_leader = {{{majority_floor_leader4|}}} | majority_leader = {{#if: {{{majorityleader4|}}} | {{{majorityleader4}}} | {{{majority_leader4|}}} }} | majority = {{{majority4|}}} | minister = {{{minister4|}}} | minority_leader = {{#if: {{{minorityleader4|}}} | {{{minorityleader4}}} | {{{minority_leader4|}}} }} | monarch = {{{monarch4|}}} | nominator = {{{nominator4|}}} | office = {{{office4|}}} | order = {{{order4|}}} | parliament = {{{parliament4|}}} | parliamentarygroup = {{{parliamentarygroup4|}}} | predecessor = {{{predecessor4|}}} | preceding = {{{preceding4|}}} | preceded = {{{preceded4|}}} | premier = {{{premier4|}}} | president = {{{president4|}}} | primeminister = {{{primeminister4|}}} | riding = {{{riding4|}}} | state_assembly = {{{state_assembly4|}}} | state_delegate = {{{state_delegate4|}}} | state_house = {{{state_house4|}}} | state_legislature = {{{state_legislature4|}}} | state_senate = {{{state_senate4|}}} | state = {{{state4|}}} | status = {{{status4|}}} | subterm = {{{subterm4|}}} | suboffice = {{{suboffice4|}}} | succeeded = {{{succeeded4|}}} | succeeding = {{{succeeding4|}}} | successor = {{{successor4|}}} | taoiseach = {{{taoiseach4|}}} | termlabel = {{{term_label4|{{{termlabel4|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend4|}}}|{{{termend4}}}|{{{term_end4|}}}}} | termstart = {{#if:{{{termstart4|}}}|{{{termstart4}}}|{{{term_start4|}}}}} | term = {{{term4|}}} | title = {{{title4|}}} | vicegovernor = {{{vicegovernor4|}}} | vicepresident = {{{vicepresident4|}}} | vicepremier = {{{vicepremier4|}}} | viceprimeminister = {{{viceprimeminister4|}}} | party = {{{party|}}} | prior_term = {{{prior_term4|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname5|}}} | 1namedata = {{{1namedata5|}}} | 2blankname = {{{2blankname5|}}} | 2namedata = {{{2namedata5|}}} | 3blankname = {{{3blankname5|}}} | 3namedata = {{{3namedata5|}}} | 4blankname = {{{4blankname5|}}} | 4namedata = {{{4namedata5|}}} | 5blankname = {{{5blankname5|}}} | 5namedata = {{{5namedata5|}}} | alongside = {{{alongside5|}}} | ambassador_from = {{{ambassador_from5|}}} | appointer = {{#if: {{{appointer5|}}} | {{{appointer5}}} | {{{appointed5|}}} }} | assembly = {{{assembly5|}}} | assuming = {{{assuming5|}}} | chancellor = {{{chancellor5|}}} | co-leader = {{{co-leader5|}}} | constituency_{{#if:{{{constituency_AM5|}}}|AM|MP}} = {{#if: {{{constituency_AM5|}}} | {{{constituency_AM5}}} | {{{constituency_MP5|}}} }} | constituency = {{{constituency5|}}} | convocation = {{{convocation5|}}} | country = {{{country5|}}} | deputy = {{{deputy5|}}} | deputyminister = {{{deputyminister5|}}} | headminister = {{{headminister5|}}} | district = {{{district5|}}} | firstminister = {{{firstminister5|}}} | governor-general = {{{governor-general5|}}} | governor_general = {{{governor_general5|}}} | governor = {{{governor5|}}} | jr/sr = {{{jr/sr5|}}} | jr/sr and state = {{{jr/sr and state5|}}} | leader = {{{leader5|}}} | legislature = {{{legislature5|}}} | lieutenant_governor = {{{lieutenant_governor5|}}} | lieutenant = {{{lieutenant5|}}} | minister_from = {{{minister_from5|}}} | minority_floor_leader = {{{minority_floor_leader5|}}} | majority_floor_leader = {{{majority_floor_leader5|}}} | majority_leader = {{#if: {{{majorityleader5|}}} | {{{majorityleader5}}} | {{{majority_leader5|}}} }} | majority = {{{majority5|}}} | minister = {{{minister5|}}} | minority_leader = {{#if: {{{minorityleader5|}}} | {{{minorityleader5}}} | {{{minority_leader5|}}} }} | monarch = {{{monarch5|}}} | nominator = {{{nominator5|}}} | office = {{{office5|}}} | order = {{{order5|}}} | parliament = {{{parliament5|}}} | parliamentarygroup = {{{parliamentarygroup5|}}} | predecessor = {{{predecessor5|}}} | preceding = {{{preceding5|}}} | preceded = {{{preceded5|}}} | premier = {{{premier5|}}} | president = {{{president5|}}} | primeminister = {{{primeminister5|}}} | riding = {{{riding5|}}} | state_assembly = {{{state_assembly5|}}} | state_delegate = {{{state_delegate5|}}} | state_house = {{{state_house5|}}} | state_legislature = {{{state_legislature5|}}} | state_senate = {{{state_senate5|}}} | state = {{{state5|}}} | status = {{{status5|}}} | subterm = {{{subterm5|}}} | suboffice = {{{suboffice5|}}} | succeeded = {{{succeeded5|}}} | succeeding = {{{succeeding5|}}} | successor = {{{successor5|}}} | taoiseach = {{{taoiseach5|}}} | termlabel = {{{term_label5|{{{termlabel5|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend5|}}}|{{{termend5}}}|{{{term_end5|}}}}} | termstart = {{#if:{{{termstart5|}}}|{{{termstart5}}}|{{{term_start5|}}}}} | term = {{{term5|}}} | title = {{{title5|}}} | vicegovernor = {{{vicegovernor5|}}} | vicepresident = {{{vicepresident5|}}} | vicepremier = {{{vicepremier5|}}} | viceprimeminister = {{{viceprimeminister5|}}} | party = {{{party|}}} | prior_term = {{{prior_term5|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname6|}}} | 1namedata = {{{1namedata6|}}} | 2blankname = {{{2blankname6|}}} | 2namedata = {{{2namedata6|}}} | 3blankname = {{{3blankname6|}}} | 3namedata = {{{3namedata6|}}} | 4blankname = {{{4blankname6|}}} | 4namedata = {{{4namedata6|}}} | 5blankname = {{{5blankname6|}}} | 5namedata = {{{5namedata6|}}} | alongside = {{{alongside6|}}} | ambassador_from = {{{ambassador_from6|}}} | appointer = {{#if: {{{appointer6|}}} | {{{appointer6}}} | {{{appointed6|}}} }} | assembly = {{{assembly6|}}} | assuming = {{{assuming6|}}} | chancellor = {{{chancellor6|}}} | co-leader = {{{co-leader6|}}} | constituency_{{#if:{{{constituency_AM6|}}}|AM|MP}} = {{#if: {{{constituency_AM6|}}} | {{{constituency_AM6}}} | {{{constituency_MP6|}}} }} | constituency = {{{constituency6|}}} | convocation = {{{convocation6|}}} | country = {{{country6|}}} | deputy = {{{deputy6|}}} | deputyminister = {{{deputyminister6|}}} | headminister = {{{headminister6|}}} | district = {{{district6|}}} | firstminister = {{{firstminister6|}}} | governor-general = {{{governor-general6|}}} | governor_general = {{{governor_general6|}}} | governor = {{{governor6|}}} | jr/sr = {{{jr/sr6|}}} | jr/sr and state = {{{jr/sr and state6|}}} | leader = {{{leader6|}}} | legislature = {{{legislature6|}}} | lieutenant_governor = {{{lieutenant_governor6|}}} | lieutenant = {{{lieutenant6|}}} | minority_floor_leader = {{{minority_floor_leader6|}}} | minister_from = {{{minister_from6|}}} | majority_floor_leader = {{{majority_floor_leader6|}}} | majority_leader = {{#if: {{{majorityleader6|}}} | {{{majorityleader6}}} | {{{majority_leader6|}}} }} | majority = {{{majority6|}}} | minister = {{{minister6|}}} | minority_leader = {{#if: {{{minorityleader6|}}} | {{{minorityleader6}}} | {{{minority_leader6|}}} }} | monarch = {{{monarch6|}}} | nominator = {{{nominator6|}}} | office = {{{office6|}}} | order = {{{order6|}}} | parliament = {{{parliament6|}}} | parliamentarygroup = {{{parliamentarygroup6|}}} | predecessor = {{{predecessor6|}}} | preceding = {{{preceding6|}}} | preceded = {{{preceded6|}}} | premier = {{{premier6|}}} | president = {{{president6|}}} | primeminister = {{{primeminister6|}}} | riding = {{{riding6|}}} | state_assembly = {{{state_assembly6|}}} | state_delegate = {{{state_delegate6|}}} | state_house = {{{state_house6|}}} | state_legislature = {{{state_legislature6|}}} | state_senate = {{{state_senate6|}}} | state = {{{state6|}}} | status = {{{status6|}}} | subterm = {{{subterm6|}}} | suboffice = {{{suboffice6|}}} | succeeded = {{{succeeded6|}}} | succeeding = {{{succeeding6|}}} | successor = {{{successor6|}}} | taoiseach = {{{taoiseach6|}}} | termlabel = {{{term_label6|{{{termlabel6|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend6|}}}|{{{termend6}}}|{{{term_end6|}}}}} | termstart = {{#if:{{{termstart6|}}}|{{{termstart6}}}|{{{term_start6|}}}}} | term = {{{term6|}}} | title = {{{title6|}}} | vicegovernor = {{{vicegovernor6|}}} | vicepresident = {{{vicepresident6|}}} | vicepremier = {{{vicepremier6|}}} | viceprimeminister = {{{viceprimeminister6|}}} | party = {{{party|}}} | prior_term = {{{prior_term6|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname7|}}} | 1namedata = {{{1namedata7|}}} | 2blankname = {{{2blankname7|}}} | 2namedata = {{{2namedata7|}}} | 3blankname = {{{3blankname7|}}} | 3namedata = {{{3namedata7|}}} | 4blankname = {{{4blankname7|}}} | 4namedata = {{{4namedata7|}}} | 5blankname = {{{5blankname7|}}} | 5namedata = {{{5namedata7|}}} | alongside = {{{alongside7|}}} | ambassador_from = {{{ambassador_from7|}}} | appointer = {{#if: {{{appointer7|}}} | {{{appointer7}}} | {{{appointed7|}}} }} | assembly = {{{assembly7|}}} | assuming = {{{assuming7|}}} | chancellor = {{{chancellor7|}}} | co-leader = {{{co-leader7|}}} | constituency_{{#if:{{{constituency_AM7|}}}|AM|MP}} = {{#if: {{{constituency_AM7|}}} | {{{constituency_AM7}}} | {{{constituency_MP7|}}} }} | constituency = {{{constituency7|}}} | convocation = {{{convocation7|}}} | country = {{{country7|}}} | deputy = {{{deputy7|}}} | deputyminister = {{{deputyminister7|}}} | headminister = {{{headminister7|}}} | district = {{{district7|}}} | firstminister = {{{firstminister7|}}} | governor-general = {{{governor-general7|}}} | governor_general = {{{governor_general7|}}} | governor = {{{governor7|}}} | jr/sr = {{{jr/sr7|}}} | jr/sr and state = {{{jr/sr and state7|}}} | leader = {{{leader7|}}} | legislature = {{{legislature7|}}} | lieutenant_governor = {{{lieutenant_governor7|}}} | lieutenant = {{{lieutenant7|}}} | minister_from = {{{minister_from7|}}} | minority_floor_leader = {{{minority_floor_leader7|}}} | majority_floor_leader = {{{majority_floor_leader7|}}} | majority_leader = {{#if: {{{majorityleader7|}}} | {{{majorityleader7}}} | {{{majority_leader7|}}} }} | majority = {{{majority7|}}} | minister = {{{minister7|}}} | minority_leader = {{#if: {{{minorityleader7|}}} | {{{minorityleader7}}} | {{{minority_leader7|}}} }} | monarch = {{{monarch7|}}} | nominator = {{{nominator7|}}} | office = {{{office7|}}} | order = {{{order7|}}} | parliament = {{{parliament7|}}} | parliamentarygroup = {{{parliamentarygroup7|}}} | predecessor = {{{predecessor7|}}} | preceding = {{{preceding7|}}} | preceded = {{{preceded7|}}} | premier = {{{premier7|}}} | president = {{{president7|}}} | primeminister = {{{primeminister7|}}} | riding = {{{riding7|}}} | state_assembly = {{{state_assembly7|}}} | state_delegate = {{{state_delegate7|}}} | state_house = {{{state_house7|}}} | state_legislature = {{{state_legislature7|}}} | state_senate = {{{state_senate7|}}} | state = {{{state7|}}} | status = {{{status7|}}} | subterm = {{{subterm7|}}} | suboffice = {{{suboffice7|}}} | succeeded = {{{succeeded7|}}} | succeeding = {{{succeeding7|}}} | successor = {{{successor7|}}} | taoiseach = {{{taoiseach7|}}} | termlabel = {{{term_label7|{{{termlabel7|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend7|}}}|{{{termend7}}}|{{{term_end7|}}}}} | termstart = {{#if:{{{termstart7|}}}|{{{termstart7}}}|{{{term_start7|}}}}} | term = {{{term7|}}} | title = {{{title7|}}} | vicegovernor = {{{vicegovernor7|}}} | vicepresident = {{{vicepresident7|}}} | vicepremier = {{{vicepremier7|}}} | viceprimeminister = {{{viceprimeminister7|}}} | party = {{{party|}}} | prior_term = {{{prior_term7|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname8|}}} | 1namedata = {{{1namedata8|}}} | 2blankname = {{{2blankname8|}}} | 2namedata = {{{2namedata8|}}} | 3blankname = {{{3blankname8|}}} | 3namedata = {{{3namedata8|}}} | 4blankname = {{{4blankname8|}}} | 4namedata = {{{4namedata8|}}} | 5blankname = {{{5blankname8|}}} | 5namedata = {{{5namedata8|}}} | alongside = {{{alongside8|}}} | ambassador_from = {{{ambassador_from8|}}} | appointer = {{#if: {{{appointer8|}}} | {{{appointer8}}} | {{{appointed8|}}} }} | assembly = {{{assembly8|}}} | assuming = {{{assuming8|}}} | chancellor = {{{chancellor8|}}} | co-leader = {{{co-leader8|}}} | constituency_{{#if:{{{constituency_AM8|}}}|AM|MP}} = {{#if: {{{constituency_AM8|}}} | {{{constituency_AM8}}} | {{{constituency_MP8|}}} }} | constituency = {{{constituency8|}}} | convocation = {{{convocation8|}}} | country = {{{country8|}}} | deputy = {{{deputy8|}}} | deputyminister = {{{deputyminister8|}}} | headminister = {{{headminister8|}}} | district = {{{district8|}}} | firstminister = {{{firstminister8|}}} | governor-general = {{{governor-general8|}}} | governor_general = {{{governor_general8|}}} | governor = {{{governor8|}}} | jr/sr = {{{jr/sr8|}}} | jr/sr and state = {{{jr/sr and state8|}}} | leader = {{{leader8|}}} | legislature = {{{legislature8|}}} | lieutenant_governor = {{{lieutenant_governor8|}}} | lieutenant = {{{lieutenant8|}}} | minister_from = {{{minister_from8|}}} | minority_floor_leader = {{{minority_floor_leader8|}}} | majority_floor_leader = {{{majority_floor_leader8|}}} | majority_leader = {{#if: {{{majorityleader8|}}} | {{{majorityleader8}}} | {{{majority_leader8|}}} }} | majority = {{{majority8|}}} | minister = {{{minister8|}}} | minority_leader = {{#if: {{{minorityleader8|}}} | {{{minorityleader8}}} | {{{minority_leader8|}}} }} | monarch = {{{monarch8|}}} | nominator = {{{nominator8|}}} | office = {{{office8|}}} | order = {{{order8|}}} | parliament = {{{parliament8|}}} | parliamentarygroup = {{{parliamentarygroup8|}}} | predecessor = {{{predecessor8|}}} | preceding = {{{preceding8|}}} | preceded = {{{preceded8|}}} | premier = {{{premier8|}}} | president = {{{president8|}}} | primeminister = {{{primeminister8|}}} | riding = {{{riding8|}}} | state_assembly = {{{state_assembly8|}}} | state_delegate = {{{state_delegate8|}}} | state_house = {{{state_house8|}}} | state_legislature = {{{state_legislature8|}}} | state_senate = {{{state_senate8|}}} | state = {{{state8|}}} | status = {{{status8|}}} | subterm = {{{subterm8|}}} | suboffice = {{{suboffice8|}}} | succeeded = {{{succeeded8|}}} | succeeding = {{{succeeding8|}}} | successor = {{{successor8|}}} | taoiseach = {{{taoiseach8|}}} | termlabel = {{{term_label8|{{{termlabel8|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend8|}}}|{{{termend8}}}|{{{term_end8|}}}}} | termstart = {{#if:{{{termstart8|}}}|{{{termstart8}}}|{{{term_start8|}}}}} | term = {{{term8|}}} | title = {{{title8|}}} | vicegovernor = {{{vicegovernor8|}}} | vicepresident = {{{vicepresident8|}}} | vicepremier = {{{vicepremier8|}}} | viceprimeminister = {{{viceprimeminister8|}}} | party = {{{party|}}} | prior_term = {{{prior_term8|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname9|}}} | 1namedata = {{{1namedata9|}}} | 2blankname = {{{2blankname9|}}} | 2namedata = {{{2namedata9|}}} | 3blankname = {{{3blankname9|}}} | 3namedata = {{{3namedata9|}}} | 4blankname = {{{4blankname9|}}} | 4namedata = {{{4namedata9|}}} | 5blankname = {{{5blankname9|}}} | 5namedata = {{{5namedata9|}}} | alongside = {{{alongside9|}}} | ambassador_from = {{{ambassador_from9|}}} | appointer = {{#if: {{{appointer9|}}} | {{{appointer9}}} | {{{appointed9|}}} }} | assembly = {{{assembly9|}}} | assuming = {{{assuming9|}}} | chancellor = {{{chancellor9|}}} | co-leader = {{{co-leader9|}}} | constituency_{{#if:{{{constituency_AM9|}}}|AM|MP}} = {{#if: {{{constituency_AM9|}}} | {{{constituency_AM9}}} | {{{constituency_MP9|}}} }} | constituency = {{{constituency9|}}} | convocation = {{{convocation9|}}} | country = {{{country9|}}} | deputy = {{{deputy9|}}} | deputyminister = {{{deputyminister9|}}} | headminister = {{{headminister9|}}} | district = {{{district9|}}} | firstminister = {{{firstminister9|}}} | governor-general = {{{governor-general9|}}} | governor_general = {{{governor_general9|}}} | governor = {{{governor9|}}} | jr/sr = {{{jr/sr9|}}} | jr/sr and state = {{{jr/sr and state9|}}} | leader = {{{leader9|}}} | legislature = {{{legislature9|}}} | lieutenant_governor = {{{lieutenant_governor9|}}} | lieutenant = {{{lieutenant9|}}} | minister_from = {{{minister_from9|}}} | minority_floor_leader = {{{minority_floor_leader9|}}} | majority_floor_leader = {{{majority_floor_leader9|}}} | majority_leader = {{#if: {{{majorityleader9|}}} | {{{majorityleader9}}} | {{{majority_leader9|}}} }} | majority = {{{majority9|}}} | minister = {{{minister9|}}} | minority_leader = {{#if: {{{minorityleader9|}}} | {{{minorityleader9}}} | {{{minority_leader9|}}} }} | monarch = {{{monarch9|}}} | nominator = {{{nominator9|}}} | office = {{{office9|}}} | order = {{{order9|}}} | parliament = {{{parliament9|}}} | parliamentarygroup = {{{parliamentarygroup9|}}} | predecessor = {{{predecessor9|}}} | preceding = {{{preceding9|}}} | preceded = {{{preceded9|}}} | premier = {{{premier9|}}} | president = {{{president9|}}} | primeminister = {{{primeminister9|}}} | riding = {{{riding9|}}} | state_assembly = {{{state_assembly9|}}} | state_delegate = {{{state_delegate9|}}} | state_house = {{{state_house9|}}} | state_legislature = {{{state_legislature9|}}} | state_senate = {{{state_senate9|}}} | state = {{{state9|}}} | status = {{{status9|}}} | subterm = {{{subterm9|}}} | suboffice = {{{suboffice9|}}} | succeeded = {{{succeeded9|}}} | succeeding = {{{succeeding9|}}} | successor = {{{successor9|}}} | taoiseach = {{{taoiseach9|}}} | termlabel = {{{term_label9|{{{termlabel9|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend9|}}}|{{{termend9}}}|{{{term_end9|}}}}} | termstart = {{#if:{{{termstart9|}}}|{{{termstart9}}}|{{{term_start9|}}}}} | term = {{{term9|}}} | title = {{{title9|}}} | vicegovernor = {{{vicegovernor9|}}} | vicepresident = {{{vicepresident9|}}} | vicepremier = {{{vicepremier9|}}} | viceprimeminister = {{{viceprimeminister9|}}} | party = {{{party|}}} | prior_term = {{{prior_term9|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname10|}}} | 1namedata = {{{1namedata10|}}} | 2blankname = {{{2blankname10|}}} | 2namedata = {{{2namedata10|}}} | 3blankname = {{{3blankname10|}}} | 3namedata = {{{3namedata10|}}} | 4blankname = {{{4blankname10|}}} | 4namedata = {{{4namedata10|}}} | 5blankname = {{{5blankname10|}}} | 5namedata = {{{5namedata10|}}} | alongside = {{{alongside10|}}} | ambassador_from = {{{ambassador_from10|}}} | appointer = {{#if: {{{appointer10|}}} | {{{appointer10}}} | {{{appointed10|}}} }} | assembly = {{{assembly10|}}} | assuming = {{{assuming10|}}} | chancellor = {{{chancellor10|}}} | co-leader = {{{co-leader10|}}} | constituency_{{#if:{{{constituency_AM10|}}}|AM|MP}} = {{#if: {{{constituency_AM10|}}} | {{{constituency_AM10}}} | {{{constituency_MP10|}}} }} | constituency = {{{constituency10|}}} | convocation = {{{convocation10|}}} | country = {{{country10|}}} | deputy = {{{deputy10|}}} | deputyminister = {{{deputyminister10|}}} | headminister = {{{headminister10|}}} | district = {{{district10|}}} | firstminister = {{{firstminister10|}}} | governor-general = {{{governor-general10|}}} | governor_general = {{{governor_general10|}}} | governor = {{{governor10|}}} | jr/sr = {{{jr/sr10|}}} | jr/sr and state = {{{jr/sr and state10|}}} | leader = {{{leader10|}}} | legislature = {{{legislature10|}}} | lieutenant_governor = {{{lieutenant_governor10|}}} | lieutenant = {{{lieutenant10|}}} | minister_from = {{{minister_from10|}}} | minority_floor_leader = {{{minority_floor_leader10|}}} | majority_floor_leader = {{{majority_floor_leader10|}}} | majority_leader = {{#if: {{{majorityleader10|}}} | {{{majorityleader10}}} | {{{majority_leader10|}}} }} | majority = {{{majority10|}}} | minister = {{{minister10|}}} | minority_leader = {{#if: {{{minorityleader10|}}} | {{{minorityleader10}}} | {{{minority_leader10|}}} }} | monarch = {{{monarch10|}}} | nominator = {{{nominator10|}}} | office = {{{office10|}}} | order = {{{order10|}}} | parliament = {{{parliament10|}}} | parliamentarygroup = {{{parliamentarygroup10|}}} | predecessor = {{{predecessor10|}}} | preceding = {{{preceding10|}}} | preceded = {{{preceded10|}}} | premier = {{{premier10|}}} | president = {{{president10|}}} | primeminister = {{{primeminister10|}}} | riding = {{{riding10|}}} | state_assembly = {{{state_assembly10|}}} | state_delegate = {{{state_delegate10|}}} | state_house = {{{state_house10|}}} | state_legislature = {{{state_legislature10|}}} | state_senate = {{{state_senate10|}}} | state = {{{state10|}}} | status = {{{status10|}}} | subterm = {{{subterm10|}}} | suboffice = {{{suboffice10|}}} | succeeded = {{{succeeded10|}}} | succeeding = {{{succeeding10|}}} | successor = {{{successor10|}}} | taoiseach = {{{taoiseach10|}}} | termlabel = {{{term_label10|{{{termlabel10|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend10|}}}|{{{termend10}}}|{{{term_end10|}}}}} | termstart = {{#if:{{{termstart10|}}}|{{{termstart10}}}|{{{term_start10|}}}}} | term = {{{term10|}}} | title = {{{title10|}}} | vicegovernor = {{{vicegovernor10|}}} | vicepresident = {{{vicepresident10|}}} | vicepremier = {{{vicepremier10|}}} | viceprimeminister = {{{viceprimeminister10|}}} | party = {{{party|}}} | prior_term = {{{prior_term10|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname11|}}} | 1namedata = {{{1namedata11|}}} | 2blankname = {{{2blankname11|}}} | 2namedata = {{{2namedata11|}}} | 3blankname = {{{3blankname11|}}} | 3namedata = {{{3namedata11|}}} | 4blankname = {{{4blankname11|}}} | 4namedata = {{{4namedata11|}}} | 5blankname = {{{5blankname11|}}} | 5namedata = {{{5namedata11|}}} | alongside = {{{alongside11|}}} | ambassador_from = {{{ambassador_from11|}}} | appointer = {{#if: {{{appointer11|}}} | {{{appointer11}}} | {{{appointed11|}}} }} | assembly = {{{assembly11|}}} | assuming = {{{assuming11|}}} | chancellor = {{{chancellor11|}}} | co-leader = {{{co-leader11|}}} | constituency_{{#if:{{{constituency_AM11|}}}|AM|MP}} = {{#if: {{{constituency_AM11|}}} | {{{constituency_AM11}}} | {{{constituency_MP11|}}} }} | constituency = {{{constituency11|}}} | convocation = {{{convocation11|}}} | country = {{{country11|}}} | deputy = {{{deputy11|}}} | deputyminister = {{{deputyminister11|}}} | headminister = {{{headminister11|}}} | district = {{{district11|}}} | firstminister = {{{firstminister11|}}} | governor-general = {{{governor-general11|}}} | governor_general = {{{governor_general11|}}} | governor = {{{governor11|}}} | jr/sr = {{{jr/sr11|}}} | jr/sr and state = {{{jr/sr and state11|}}} | leader = {{{leader11|}}} | legislature = {{{legislature11|}}} | lieutenant_governor = {{{lieutenant_governor11|}}} | lieutenant = {{{lieutenant11|}}} | minister_from = {{{minister_from11|}}} | minority_floor_leader = {{{minority_floor_leader11|}}} | majority_floor_leader = {{{majority_floor_leader11|}}} | majority_leader = {{#if: {{{majorityleader11|}}} | {{{majorityleader11}}} | {{{majority_leader11|}}} }} | majority = {{{majority11|}}} | minister = {{{minister11|}}} | minority_leader = {{#if: {{{minorityleader11|}}} | {{{minorityleader11}}} | {{{minority_leader11|}}} }} | monarch = {{{monarch11|}}} | nominator = {{{nominator11|}}} | office = {{{office11|}}} | order = {{{order11|}}} | parliament = {{{parliament11|}}} | parliamentarygroup = {{{parliamentarygroup11|}}} | predecessor = {{{predecessor11|}}} | preceding = {{{preceding11|}}} | preceded = {{{preceded11|}}} | premier = {{{premier11|}}} | president = {{{president11|}}} | primeminister = {{{primeminister11|}}} | riding = {{{riding11|}}} | state_assembly = {{{state_assembly11|}}} | state_delegate = {{{state_delegate11|}}} | state_house = {{{state_house11|}}} | state_legislature = {{{state_legislature11|}}} | state_senate = {{{state_senate11|}}} | state = {{{state11|}}} | status = {{{status11|}}} | subterm = {{{subterm11|}}} | suboffice = {{{suboffice11|}}} | succeeded = {{{succeeded11|}}} | succeeding = {{{succeeding11|}}} | successor = {{{successor11|}}} | taoiseach = {{{taoiseach11|}}} | termlabel = {{{term_label11|{{{termlabel11|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend11|}}}|{{{termend11}}}|{{{term_end11|}}}}} | termstart = {{#if:{{{termstart11|}}}|{{{termstart11}}}|{{{term_start11|}}}}} | term = {{{term11|}}} | title = {{{title11|}}} | vicegovernor = {{{vicegovernor11|}}} | vicepresident = {{{vicepresident11|}}} | vicepremier = {{{vicepremier11|}}} | viceprimeminister = {{{viceprimeminister11|}}} | party = {{{party|}}} | prior_term = {{{prior_term11|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname12|}}} | 1namedata = {{{1namedata12|}}} | 2blankname = {{{2blankname12|}}} | 2namedata = {{{2namedata12|}}} | 3blankname = {{{3blankname12|}}} | 3namedata = {{{3namedata12|}}} | 4blankname = {{{4blankname12|}}} | 4namedata = {{{4namedata12|}}} | 5blankname = {{{5blankname12|}}} | 5namedata = {{{5namedata12|}}} | alongside = {{{alongside12|}}} | ambassador_from = {{{ambassador_from12|}}} | appointer = {{#if: {{{appointer12|}}} | {{{appointer12}}} | {{{appointed12|}}} }} | assembly = {{{assembly12|}}} | assuming = {{{assuming12|}}} | chancellor = {{{chancellor12|}}} | co-leader = {{{co-leader12|}}} | constituency_{{#if:{{{constituency_AM12|}}}|AM|MP}} = {{#if: {{{constituency_AM12|}}} | {{{constituency_AM12}}} | {{{constituency_MP12|}}} }} | constituency = {{{constituency12|}}} | convocation = {{{convocation12|}}} | country = {{{country12|}}} | deputy = {{{deputy12|}}} | deputyminister = {{{deputyminister12|}}} | headminister = {{{headminister12|}}} | district = {{{district12|}}} | firstminister = {{{firstminister12|}}} | governor-general = {{{governor-general12|}}} | governor_general = {{{governor_general12|}}} | governor = {{{governor12|}}} | jr/sr = {{{jr/sr12|}}} | jr/sr and state = {{{jr/sr and state12|}}} | leader = {{{leader12|}}} | legislature = {{{legislature12|}}} | lieutenant_governor = {{{lieutenant_governor12|}}} | lieutenant = {{{lieutenant12|}}} | minister_from = {{{minister_from12|}}} | minority_floor_leader = {{{minority_floor_leader12|}}} | majority_floor_leader = {{{majority_floor_leader12|}}} | majority_leader = {{#if: {{{majorityleader12|}}} | {{{majorityleader12}}} | {{{majority_leader12|}}} }} | majority = {{{majority12|}}} | minister = {{{minister12|}}} | minority_leader = {{#if: {{{minorityleader12|}}} | {{{minorityleader12}}} | {{{minority_leader12|}}} }} | monarch = {{{monarch12|}}} | nominator = {{{nominator12|}}} | office = {{{office12|}}} | order = {{{order12|}}} | parliament = {{{parliament12|}}} | parliamentarygroup = {{{parliamentarygroup12|}}} | predecessor = {{{predecessor12|}}} | preceding = {{{preceding12|}}} | preceded = {{{preceded12|}}} | premier = {{{premier12|}}} | president = {{{president12|}}} | primeminister = {{{primeminister12|}}} | riding = {{{riding12|}}} | state_assembly = {{{state_assembly12|}}} | state_delegate = {{{state_delegate12|}}} | state_house = {{{state_house12|}}} | state_legislature = {{{state_legislature12|}}} | state_senate = {{{state_senate12|}}} | state = {{{state12|}}} | status = {{{status12|}}} | subterm = {{{subterm12|}}} | suboffice = {{{suboffice12|}}} | succeeded = {{{succeeded12|}}} | succeeding = {{{succeeding12|}}} | successor = {{{successor12|}}} | taoiseach = {{{taoiseach12|}}} | termlabel = {{{term_label12|{{{termlabel12|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend12|}}}|{{{termend12}}}|{{{term_end12|}}}}} | termstart = {{#if:{{{termstart12|}}}|{{{termstart12}}}|{{{term_start12|}}}}} | term = {{{term12|}}} | title = {{{title12|}}} | vicegovernor = {{{vicegovernor12|}}} | vicepresident = {{{vicepresident12|}}} | vicepremier = {{{vicepremier12|}}} | viceprimeminister = {{{viceprimeminister12|}}} | party = {{{party|}}} | prior_term = {{{prior_term12|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname13|}}} | 1namedata = {{{1namedata13|}}} | 2blankname = {{{2blankname13|}}} | 2namedata = {{{2namedata13|}}} | 3blankname = {{{3blankname13|}}} | 3namedata = {{{3namedata13|}}} | 4blankname = {{{4blankname13|}}} | 4namedata = {{{4namedata13|}}} | 5blankname = {{{5blankname13|}}} | 5namedata = {{{5namedata13|}}} | alongside = {{{alongside13|}}} | ambassador_from = {{{ambassador_from13|}}} | appointer = {{#if: {{{appointer13|}}} | {{{appointer13}}} | {{{appointed13|}}} }} | assembly = {{{assembly13|}}} | assuming = {{{assuming13|}}} | chancellor = {{{chancellor13|}}} | co-leader = {{{co-leader13|}}} | constituency_{{#if:{{{constituency_AM13|}}}|AM|MP}} = {{#if: {{{constituency_AM13|}}} | {{{constituency_AM13}}} | {{{constituency_MP13|}}} }} | constituency = {{{constituency13|}}} | convocation = {{{convocation13|}}} | country = {{{country13|}}} | deputy = {{{deputy13|}}} | deputyminister = {{{deputyminister13|}}} | headminister = {{{headminister13|}}} | district = {{{district13|}}} | firstminister = {{{firstminister13|}}} | governor-general = {{{governor-general13|}}} | governor_general = {{{governor_general13|}}} | governor = {{{governor13|}}} | jr/sr = {{{jr/sr13|}}} | jr/sr and state = {{{jr/sr and state13|}}} | leader = {{{leader13|}}} | legislature = {{{legislature13|}}} | lieutenant_governor = {{{lieutenant_governor13|}}} | lieutenant = {{{lieutenant13|}}} | minister_from = {{{minister_from13|}}} | minority_floor_leader = {{{minority_floor_leader13|}}} | majority_floor_leader = {{{majority_floor_leader13|}}} | majority_leader = {{#if: {{{majorityleader13|}}} | {{{majorityleader13}}} | {{{majority_leader13|}}} }} | majority = {{{majority13|}}} | minister = {{{minister13|}}} | minority_leader = {{#if: {{{minorityleader13|}}} | {{{minorityleader13}}} | {{{minority_leader13|}}} }} | monarch = {{{monarch13|}}} | nominator = {{{nominator13|}}} | office = {{{office13|}}} | order = {{{order13|}}} | parliament = {{{parliament13|}}} | parliamentarygroup = {{{parliamentarygroup13|}}} | predecessor = {{{predecessor13|}}} | preceding = {{{preceding13|}}} | preceded = {{{preceded13|}}} | premier = {{{premier13|}}} | president = {{{president13|}}} | primeminister = {{{primeminister13|}}} | riding = {{{riding13|}}} | state_assembly = {{{state_assembly13|}}} | state_delegate = {{{state_delegate13|}}} | state_house = {{{state_house13|}}} | state_legislature = {{{state_legislature13|}}} | state_senate = {{{state_senate13|}}} | state = {{{state13|}}} | status = {{{status13|}}} | subterm = {{{subterm13|}}} | suboffice = {{{suboffice13|}}} | succeeded = {{{succeeded13|}}} | succeeding = {{{succeeding13|}}} | successor = {{{successor13|}}} | taoiseach = {{{taoiseach13|}}} | termlabel = {{{term_label13|{{{termlabel13|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend13|}}}|{{{termend13}}}|{{{term_end13|}}}}} | termstart = {{#if:{{{termstart13|}}}|{{{termstart13}}}|{{{term_start13|}}}}} | term = {{{term13|}}} | title = {{{title13|}}} | vicegovernor = {{{vicegovernor13|}}} | vicepresident = {{{vicepresident13|}}} | vicepremier = {{{vicepremier13|}}} | viceprimeminister = {{{viceprimeminister13|}}} | party = {{{party|}}} | prior_term = {{{prior_term13|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname14|}}} | 1namedata = {{{1namedata14|}}} | 2blankname = {{{2blankname14|}}} | 2namedata = {{{2namedata14|}}} | 3blankname = {{{3blankname14|}}} | 3namedata = {{{3namedata14|}}} | 4blankname = {{{4blankname14|}}} | 4namedata = {{{4namedata14|}}} | 5blankname = {{{5blankname14|}}} | 5namedata = {{{5namedata14|}}} | alongside = {{{alongside14|}}} | ambassador_from = {{{ambassador_from14|}}} | appointer = {{#if: {{{appointer14|}}} | {{{appointer14}}} | {{{appointed14|}}} }} | assembly = {{{assembly14|}}} | assuming = {{{assuming14|}}} | chancellor = {{{chancellor14|}}} | co-leader = {{{co-leader14|}}} | constituency_{{#if:{{{constituency_AM14|}}}|AM|MP}} = {{#if: {{{constituency_AM14|}}} | {{{constituency_AM14}}} | {{{constituency_MP14|}}} }} | constituency = {{{constituency14|}}} | convocation = {{{convocation14|}}} | country = {{{country14|}}} | deputy = {{{deputy14|}}} | deputyminister = {{{deputyminister14|}}} | headminister = {{{headminister14|}}} | district = {{{district14|}}} | firstminister = {{{firstminister14|}}} | governor-general = {{{governor-general14|}}} | governor_general = {{{governor_general14|}}} | governor = {{{governor14|}}} | jr/sr = {{{jr/sr14|}}} | jr/sr and state = {{{jr/sr and state14|}}} | leader = {{{leader14|}}} | legislature = {{{legislature14|}}} | lieutenant_governor = {{{lieutenant_governor14|}}} | lieutenant = {{{lieutenant14|}}} | minister_from = {{{minister_from14|}}} | minority_floor_leader = {{{minority_floor_leader14|}}} | majority_floor_leader = {{{majority_floor_leader14|}}} | majority_leader = {{#if: {{{majorityleader14|}}} | {{{majorityleader14}}} | {{{majority_leader14|}}} }} | majority = {{{majority14|}}} | minister = {{{minister14|}}} | minority_leader = {{#if: {{{minorityleader14|}}} | {{{minorityleader14}}} | {{{minority_leader14|}}} }} | monarch = {{{monarch14|}}} | nominator = {{{nominator14|}}} | office = {{{office14|}}} | order = {{{order14|}}} | parliament = {{{parliament14|}}} | parliamentarygroup = {{{parliamentarygroup14|}}} | predecessor = {{{predecessor14|}}} | preceding = {{{preceding14|}}} | preceded = {{{preceded14|}}} | premier = {{{premier14|}}} | president = {{{president14|}}} | primeminister = {{{primeminister14|}}} | riding = {{{riding14|}}} | state_assembly = {{{state_assembly14|}}} | state_delegate = {{{state_delegate14|}}} | state_house = {{{state_house14|}}} | state_legislature = {{{state_legislature14|}}} | state_senate = {{{state_senate14|}}} | state = {{{state14|}}} | status = {{{status14|}}} | subterm = {{{subterm14|}}} | suboffice = {{{suboffice14|}}} | succeeded = {{{succeeded14|}}} | succeeding = {{{succeeding14|}}} | successor = {{{successor14|}}} | taoiseach = {{{taoiseach14|}}} | termlabel = {{{term_label14|{{{termlabel14|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend14|}}}|{{{termend14}}}|{{{term_end14|}}}}} | termstart = {{#if:{{{termstart14|}}}|{{{termstart14}}}|{{{term_start14|}}}}} | term = {{{term14|}}} | title = {{{title14|}}} | vicegovernor = {{{vicegovernor14|}}} | vicepresident = {{{vicepresident14|}}} | vicepremier = {{{vicepremier14|}}} | viceprimeminister = {{{viceprimeminister14|}}} | party = {{{party|}}} | prior_term = {{{prior_term14|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname15|}}} | 1namedata = {{{1namedata15|}}} | 2blankname = {{{2blankname15|}}} | 2namedata = {{{2namedata15|}}} | 3blankname = {{{3blankname15|}}} | 3namedata = {{{3namedata15|}}} | 4blankname = {{{4blankname15|}}} | 4namedata = {{{4namedata15|}}} | 5blankname = {{{5blankname15|}}} | 5namedata = {{{5namedata15|}}} | alongside = {{{alongside15|}}} | ambassador_from = {{{ambassador_from15|}}} | appointer = {{#if: {{{appointer15|}}} | {{{appointer15}}} | {{{appointed15|}}} }} | assembly = {{{assembly15|}}} | assuming = {{{assuming15|}}} | chancellor = {{{chancellor15|}}} | co-leader = {{{co-leader15|}}} | constituency_{{#if:{{{constituency_AM15|}}}|AM|MP}} = {{#if: {{{constituency_AM15|}}} | {{{constituency_AM15}}} | {{{constituency_MP15|}}} }} | constituency = {{{constituency15|}}} | convocation = {{{convocation15|}}} | country = {{{country15|}}} | deputy = {{{deputy15|}}} | deputyminister = {{{deputyminister15|}}} | headminister = {{{headminister15|}}} | district = {{{district15|}}} | firstminister = {{{firstminister15|}}} | governor-general = {{{governor-general15|}}} | governor_general = {{{governor_general15|}}} | governor = {{{governor15|}}} | jr/sr = {{{jr/sr15|}}} | jr/sr and state = {{{jr/sr and state15|}}} | leader = {{{leader15|}}} | legislature = {{{legislature15|}}} | lieutenant_governor = {{{lieutenant_governor15|}}} | lieutenant = {{{lieutenant15|}}} | minister_from = {{{minister_from15|}}} | minority_floor_leader = {{{minority_floor_leader15|}}} | majority_floor_leader = {{{majority_floor_leader15|}}} | majority_leader = {{#if: {{{majorityleader15|}}} | {{{majorityleader15}}} | {{{majority_leader15|}}} }} | majority = {{{majority15|}}} | minister = {{{minister15|}}} | minority_leader = {{#if: {{{minorityleader15|}}} | {{{minorityleader15}}} | {{{minority_leader15|}}} }} | monarch = {{{monarch15|}}} | nominator = {{{nominator15|}}} | office = {{{office15|}}} | order = {{{order15|}}} | parliament = {{{parliament15|}}} | parliamentarygroup = {{{parliamentarygroup15|}}} | predecessor = {{{predecessor15|}}} | preceding = {{{preceding15|}}} | preceded = {{{preceded15|}}} | premier = {{{premier15|}}} | president = {{{president15|}}} | primeminister = {{{primeminister15|}}} | riding = {{{riding15|}}} | state_assembly = {{{state_assembly15|}}} | state_delegate = {{{state_delegate15|}}} | state_house = {{{state_house15|}}} | state_legislature = {{{state_legislature15|}}} | state_senate = {{{state_senate15|}}} | state = {{{state15|}}} | status = {{{status15|}}} | subterm = {{{subterm15|}}} | suboffice = {{{suboffice15|}}} | succeeded = {{{succeeded15|}}} | succeeding = {{{succeeding15|}}} | successor = {{{successor15|}}} | taoiseach = {{{taoiseach15|}}} | termlabel = {{{term_label15|{{{termlabel15|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend15|}}}|{{{termend15}}}|{{{term_end15|}}}}} | termstart = {{#if:{{{termstart15|}}}|{{{termstart15}}}|{{{term_start15|}}}}} | term = {{{term15|}}} | title = {{{title15|}}} | vicegovernor = {{{vicegovernor15|}}} | vicepresident = {{{vicepresident15|}}} | vicepremier = {{{vicepremier15|}}} | viceprimeminister = {{{viceprimeminister15|}}} | party = {{{party|}}} | prior_term = {{{prior_term15|}}} }}}}<!-- -->{{#if:{{{nominee|}}}{{{candidate|}}}|| {{กล่องข้อมูล ผู้ดำรงตำแหน่ง/Office|color={{#ifeq:{{lc:{{{embed}}}}}|yes|#eee|lavender}} | 1blankname = {{{1blankname16|}}} | 1namedata = {{{1namedata16|}}} | 2blankname = {{{2blankname16|}}} | 2namedata = {{{2namedata16|}}} | 3blankname = {{{3blankname16|}}} | 3namedata = {{{3namedata16|}}} | 4blankname = {{{4blankname16|}}} | 4namedata = {{{4namedata16|}}} | 5blankname = {{{5blankname16|}}} | 5namedata = {{{5namedata16|}}} | alongside = {{{alongside16|}}} | ambassador_from = {{{ambassador_from16|}}} | appointer = {{#if: {{{appointer16|}}} | {{{appointer16}}} | {{{appointed16|}}} }} | assembly = {{{assembly16|}}} | assuming = {{{assuming16|}}} | chancellor = {{{chancellor16|}}} | co-leader = {{{co-leader16|}}} | constituency_{{#if:{{{constituency_AM16|}}}|AM|MP}} = {{#if: {{{constituency_AM16|}}} | {{{constituency_AM16}}} | {{{constituency_MP16|}}} }} | constituency = {{{constituency16|}}} | convocation = {{{convocation16|}}} | country = {{{country16|}}} | deputy = {{{deputy16|}}} | deputyminister = {{{deputyminister16|}}} | headminister = {{{headminister16|}}} | district = {{{district16|}}} | firstminister = {{{firstminister16|}}} | governor-general = {{{governor-general16|}}} | governor_general = {{{governor_general16|}}} | governor = {{{governor16|}}} | jr/sr = {{{jr/sr16|}}} | jr/sr and state = {{{jr/sr and state16|}}} | leader = {{{leader16|}}} | legislature = {{{legislature16|}}} | lieutenant_governor = {{{lieutenant_governor16|}}} | lieutenant = {{{lieutenant16|}}} | minister_from = {{{minister_from16|}}} | minority_floor_leader = {{{minority_floor_leader16|}}} | majority_floor_leader = {{{majority_floor_leader16|}}} | majority_leader = {{#if: {{{majorityleader16|}}} | {{{majorityleader16}}} | {{{majority_leader16|}}} }} | majority = {{{majority16|}}} | minister = {{{minister16|}}} | minority_leader = {{#if: {{{minorityleader16|}}} | {{{minorityleader16}}} | {{{minority_leader16|}}} }} | monarch = {{{monarch16|}}} | nominator = {{{nominator16|}}} | office = {{{office16|}}} | order = {{{order16|}}} | parliament = {{{parliament16|}}} | parliamentarygroup = {{{parliamentarygroup16|}}} | predecessor = {{{predecessor16|}}} | preceding = {{{preceding16|}}} | preceded = {{{preceded16|}}} | premier = {{{premier16|}}} | president = {{{president16|}}} | primeminister = {{{primeminister16|}}} | riding = {{{riding16|}}} | state_assembly = {{{state_assembly16|}}} | state_delegate = {{{state_delegate16|}}} | state_house = {{{state_house16|}}} | state_legislature = {{{state_legislature16|}}} | state_senate = {{{state_senate16|}}} | state = {{{state16|}}} | status = {{{status16|}}} | subterm = {{{subterm16|}}} | suboffice = {{{suboffice16|}}} | succeeded = {{{succeeded16|}}} | succeeding = {{{succeeding16|}}} | successor = {{{successor16|}}} | taoiseach = {{{taoiseach16|}}} | termlabel = {{{term_label16|{{{termlabel16|ดำรงตำแหน่ง}}}}}} | termend = {{#if:{{{termend16|}}}|{{{termend16}}}|{{{term_end16|}}}}} | termstart = {{#if:{{{termstart16|}}}|{{{termstart16}}}|{{{term_start16|}}}}} | term = {{{term16|}}} | title = {{{title16|}}} | vicegovernor = {{{vicegovernor16|}}} | vicepresident = {{{vicepresident16|}}} | vicepremier = {{{vicepremier16|}}} | viceprimeminister = {{{viceprimeminister16|}}} | party = {{{party|}}} | prior_term = {{{prior_term16|}}} }}}} | data2 = {{{module0|}}} <!----------Personal data----------> | header3 = {{#if:{{{pronunciation|}}}{{{birth_name|{{{birthname|}}}}}}{{{birth_date|}}}{{{birth_place|}}}{{{death_date|}}}{{{death_place|}}}{{{resting_place|{{{restingplace|}}}}}}{{{resting_place_coordinates|}}}{{{restingplacecoordinates|}}}{{{burial_place|}}}{{{citizenship|}}}{{{nationality|}}}{{{party|}}}{{{otherparty|}}}{{{spouse|}}}{{{spouses|}}}{{{spouse(s)|}}}{{{partner|}}}{{{relations|}}}{{{children|}}}{{{parents|}}}{{{mother|}}}{{{father|}}}{{{relatives|}}}{{{residence|}}}{{{education|}}}{{{alma_mater|}}}{{{occupation|}}}{{{profession|}}}{{{know for|}}}{{{know_for|}}}{{{known for|}}}{{{known_for|}}}{{{salary|}}}{{{cabinet|}}}{{{committees|}}}{{{portfolio|}}}{{{awards|}}}{{{data1|}}}{{{data2|}}}{{{data3|}}}{{{data4|}}}{{{data5|}}}|ข้อมูลส่วนบุคคล}} | label4 = เสียงอ่าน | data4 = {{{pronunciation|}}} | label5 = เกิด | data5 = {{br separated entries |1 = {{#if:{{{birth_name|{{{birthname|{{{birth name|}}}}}}}}}|<div style="display:inline" class="nickname">{{{birth_name|{{{birthname|{{{birth name}}}}}}}}}</div>}} |2 = {{{birth_date|}}} |3 = {{{birth_place|}}} }} | label6 = เสียชีวิต | data6 = {{br separated entries|{{{death_date|}}}|{{{death_place|}}}}} | label7 = {{#ifexpr: {{strfind short| {{{death_cause|}}}|ถูกลอบสังหาร}} | ลักษณะ |{{#if:{{{death_manner|}}}|ลักษณะ|สาเหตุ}} }}การเสียชีวิต | data7 = {{#if:{{{death_manner|}}}|{{{death_manner|}}}|{{{death_cause|}}}}} | label8 = ที่ไว้ศพ | class8 = label | data8 = {{br separated entries|{{{resting_place|{{{restingplace|{{{burial_place|}}} }}} }}}|{{{resting_place_coordinates|{{{restingplacecoordinates|{{{burial_place|}}} }}} }}}}} | label9 = สัญชาติ | data9 = {{{citizenship|}}} | label10 = เชื้อชาติ | data10 = {{#switch:{{Delink|{{{nationality|}}}}} | {{#ifeq:{{Country2nationality|{{Find country|{{Delink|{{{birth_place|}}}}}}}}}|{{Delink|{{{nationality|}}}}}|{{Delink|{{{nationality|}}}}}}} = | {{#ifeq:{{Find country|{{{birth_place|}}}}}|England|British}} = | #default = {{{nationality|}}} }} | label11 = ศาสนา | data11 = {{{religion|}}} | label12 = พรรคการเมือง | data12 = {{{party|}}} | label13 = {{nowrap|การเข้าร่วม}}<br />{{nowrap|พรรคการเมืองอื่น}} | data13 = {{{otherparty|{{{other_party|}}} }}} | label14 = ความสูง | data14 = {{#if:{{{height|{{{ส่วนสูง|{{{ความสูง|}}} }}} }}}|{{infobox person/height|{{{height|{{{ส่วนสูง|{{{ความสูง|}}} }}} }}}}}}} | label15 = คู่สมรส | data15 = {{{spouse|{{{spouses|{{{spouse(s)|}}}}}}}}} | label16 = คู่อาศัย | data16 = {{{partner|}}} | label17 = ญาติ | data17 = {{{relations|}}} | label18 = บุตร | data18 = {{{children|}}} | label19 = บุพการี | data19 = {{#if:{{{parents|}}}|{{{parents}}}|{{Unbulleted list|{{#if:{{{father|}}}|{{{father}}} (บิดา)}}|{{#if:{{{mother|}}}|{{{mother}}} (มารดา)}}}}}} | label20 = ความสัมพันธ์ | data20 = {{{relatives|}}} | label21 = ที่อยู่อาศัย | class21 = {{#if:{{{death_date|}}}{{{death_place|}}}||label}} | data21 = {{{residence|}}} | label22 = การศึกษา | data22 = {{{education|}}} | label23 = [[โรงเรียนแม่|ศิษย์เก่า]] | data23 = {{{alma_mater|}}} | label24 = อาชีพ | data24= {{{occupation|}}} | label25 = วิชาชีพ | data25 = {{{profession|}}} | label26 = เป็นที่รู้จักจาก | data26 = {{{know for|{{{know_for|{{{known for|{{{known_for|}}} }}} }}} }}} | label27 = เงินเดือน | data27 = {{{salary|}}} | label28 = ทรัพย์สินสุทธิ | data28 = {{{net_worth|}}} | label29 = รัฐบาล | data29 = {{{cabinet|}}} | label30 = คณะกรรมาธิการ | data30 = {{{committees|}}} | label31 = ผลงานเด่น | data31 = {{{portfolio|}}} | label32 = {{#if:{{{mawards|}}}|บำนาญ|รางวัล}} | data32 = {{{awards|}}} | label33 = {{{blank1}}} | data33 = {{{data1|}}} | label34 = {{{blank2}}} | data34 = {{{data2|}}} | label35 = {{{blank3}}} | data35 = {{{data3|}}} | label36 = {{{blank4}}} | data36 = {{{data4|}}} | label37 = {{{blank5}}} | data37 = {{{data5|}}} | label38 = ลายมือชื่อ | data38 = {{#if:{{{signature|}}}|[[File:{{{signature}}}|{{#if:{{{signature_size|}}}|{{{signature_size}}}|128x80px}}|alt={{{signature_alt|}}}|ลายมือชื่อของ{{PAGENAME}}]]}} | label39 = เว็บไซต์ | data39 = {{{website|{{{homepage|}}} }}} | label40 = ชื่อเล่น | data40 = {{{nickname|{{{other_names|{{{othernames|{{{othername|{{{nicknames|}}} }}} }}} }}} }}} | header41 = {{#if:{{{allegiance|}}}{{{branch|}}}{{{serviceyears|}}}{{{rank|}}}{{{unit|}}}{{{commands|}}}{{{battles|}}}{{{wars|}}}{{{battles/wars|}}}{{{military_blank1|}}}|ยศที่ได้รับการแต่งตั้ง}} | label42 = รับใช้ | data42 = {{{allegiance|}}} | label43 = {{#if:{{{branch_label|}}}|{{{branch_label|}}}|สังกัด}} | data43 = {{{branch|}}} | label44 = {{#if:{{{serviceyears_label|}}}|{{{serviceyears_label|}}}|ประจำการ}} | data44 = {{{serviceyears|}}} | label45 = {{#if:{{{rank_label|}}}|{{{rank_label|}}}|ยศ}} | data45 = {{{rank|}}} | label46 = {{#if:{{{unit_label|}}}|{{{unit_label|}}}|หน่วย}} | data46 = {{{unit|}}} | label47 = บังคับบัญชา | data47 = {{{commands|}}} | label48 = {{#if:{{{battles_label|}}}|{{{battles_label|}}}|สงคราม/การสู้รบ}} | data48 = {{{battles|{{{wars|{{{battles/wars|}}} }}} }}} | label49 = {{#if:{{{awards|}}}|บำเหน็จ|รางวัล}} | data49 = {{{mawards|}}} | label50 = {{{military_blank1}}} | data50 = {{{military_data1|}}} | label51 = {{{military_blank2}}} | data51 = {{{military_data2|}}} | label52 = {{{military_blank3}}} | data52 = {{{military_data3|}}} | label53 = {{{military_blank4}}} | data53 = {{{military_data4|}}} | label54 = {{{military_blank5}}} | data54 = {{{military_data5|}}} | data55 = {{{module|}}} | data56 = {{{module2|}}} | data57 = {{{module3|}}} | data58 = {{{module4|}}} | data59 = {{{module5|}}} | data60 = {{{footnotes|}}} | belowstyle = border-top: 1px solid right; font-size: 95% | below = <div>{{#if:{{{date|}}}| ณ วันที่ {{{date}}}{{#if:{{{year|}}}|, {{{year}}}}}}}</div>{{#if:{{{source|}}}|ที่มา: [{{{source}}}]}} }}{{#if:{{{pronunciation|}}}|{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[Category:Biography template using pronunciation]]}} }}{{#if:{{{1blankname0|}}}{{{1namedata0|}}}{{{2blankname0|}}}{{{2namedata0|}}}{{{3blankname0|}}}{{{3namedata0|}}}{{{4blankname0|}}}{{{4namedata0|}}}{{{5blankname0|}}}{{{5namedata0|}}}{{{alongside0|}}}{{{ambassador_from0|}}}{{{appointer0|}}}{{{assembly0|}}}{{{assuming0|}}}{{{chancellor0|}}}{{{co-leader0|}}}{{{constituency_AM0|}}}{{{constituency0|}}}{{{country0|}}}{{{deputy0|}}}{{{district0|}}}{{{firstminister0|}}}{{{governor-general0|}}}{{{governor0|}}}{{{jr/sr0|}}}{{{jr/sr and state0|}}}{{{leader0|}}}{{{legislature0|}}}{{{lieutenant_governor0|}}}{{{lieutenant0|}}}{{{minister_from0|}}}{{{minority_floor_leader0|}}}{{{majority_floor_leader0|}}}{{{majorityleader0|}}}{{{majority0|}}}{{{minister0|}}}{{{minorityleader0|}}}{{{monarch0|}}}{{{nominator0|}}}{{{office0|}}}{{{order0|}}}{{{parliament0|}}}{{{predecessor0|}}}{{{preceding0|}}}{{{preceded0|}}}{{{premier0|}}}{{{president0|}}}{{{primeminister0|}}}{{{riding0|}}}{{{state_assembly0|}}}{{{state_delegate0|}}}{{{state_house0|}}}{{{state_legislature0|}}}{{{state_senate0|}}}{{{state0|}}}{{{suboffice0|}}}{{{subterm0|}}}{{{succeeded0|}}}{{{succeeding0|}}}{{{successor0|}}}{{{taoiseach0|}}}{{{termend0|}}}{{{termstart0|}}}{{{term0|}}}{{{title0|}}}{{{vicegovernor0|}}}{{{vicepresident0|}}}{{{vicepremier0|}}}{{{viceprimeminister0|}}}{{{prior_term0|}}}{{{appointe0|}}}{{{constituency_0|}}}|{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[Category:Pages using infobox officeholder with office0]]}} }}{{#if:{{{speaker|}}}|{{#if:{{{nominee|}}}{{{candidate|}}}||{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[Category:Pages using infobox officeholder with speaker]]}}}} }}{{#invoke:Check for unknown parameters|check|unknown={{main other|{{#ifeq:{{{nocat|{{{demo|{{#ifeq:{{{categories|}}}|no|yes}}}}}}}}|yes||[[หมวดหมู่:หน้าที่ใช้กล่องข้อมูลผู้ดำรงตำแหน่งที่มีพารามิเตอร์ที่ไม่รู้จัก|_VALUE_{{PAGENAME}}]]}}}}|preview=หน้านี้ใช้ [[แม่แบบ:กล่องข้อมูล ผู้ดำรงตำแหน่ง]] ที่มีพารามิเตอร์ที่ไม่รู้จัก "_VALUE_"|ignoreblank=y| regexp1 = 1blankname[%d]* | regexp2 = 1namedata[%d]* | regexp3 = 2blankname[%d]* | regexp4 = 2namedata[%d]* | regexp5 = 3blankname[%d]* | regexp6 = 3namedata[%d]* | regexp7 = 4blankname[%d]* | regexp8 = 4namedata[%d]* | regexp9 = 5blankname[%d]* | regexp10 = 5namedata[%d]* | allegiance | alma_mater | regexp11 = alongside[%d]* | alt | regexp12 = ambassador_from[%d]* | regexp13 = appointed[%d]* | regexp14 = appointer[%d]* | regexp15 = assembly[%d]* | awards | battles | battles/wars | battles_label | birth_date | birth name | birth_name | birth_place | birthname | regexp16 = blank[%d]* | bodyclass | branch | branch_label | burial_place | cabinet | candidate | caption | categories | regexp17 = chancellor[%d]* | children | citizenship | regexp18 = co%-leader[%d]* | commands | committees | regexp19 = constituency[%d]* | regexp20 = constituency_AM[%d]* | regexp21 = constituency_MP[%d]* | regexp22 = convocation[%d]* | regexp23 = country[%d]* | regexp24 = data[%d]* | date | death_cause | death_date | death_manner | death_place | demo | regexp25 = deputy[%d]* | regexp26 = deputyminister[%d]* | regexp27 = district[%d]* | education | election_date | embed | father | regexp28 = firstminister[%d]* | footnotes | regexp29 = governor[%d]* | regexp30 = governor_general[%d]* | regexp31 = governor%-general[%d]* | regexp32 = headminister[%d]* | height | homepage | honorific_prefix | honorific-prefix | honorific_suffix | honorific-suffix | image | image name | image_name_alt | image_size | imagesize | image_upright | incumbent | regexp33 = jr/sr[%d]* | regexp34 = jr/sr and state[%d]* | know for | know_for | known for | known_for | regexp35 = leader[%d]* | regexp36 = legislature[%d]* | regexp37 = lieutenant[%d]* | regexp38 = lieutenant_governor[%d]* | mainwidth | regexp39 = majority[%d]* | regexp40 = majority_floor_leader[%d]* | regexp41 = majority_leader[%d]* | regexp42 = majorityleader[%d]* | mawards | regexp43 = military_blank[%d]* | regexp44 = military_data[%d]* | regexp45 = minister[%d]* | regexp46 = minister_from[%d]* | regexp47 = minority_floor_leader[%d]* | regexp48 = minority_leader[%d]* | regexp49 = minorityleader[%d]* | regexp50 = module[%d]* | regexp51 = monarch[%d]* | mother | name | nationality | roblox_username | net_worth | nickname | nicknames | nocat | regexp52 = nominator[%d]* | nominee | occupation | regexp53 = office[%d]* | opponent | regexp54 = order[%d]* | othername | othernames | other_names | otherparty | other_party | parents | regexp55 = parliament[%d]* | regexp56 = parliamentarygroup[%d]* | partner | party | party_election | portfolio | regexp57 = preceded[%d]* | regexp58 = preceding[%d]* | regexp59 = predecessor[%d]* | regexp60 = premier[%d]* | regexp61 = president[%d]* | regexp62 = primeminister[%d]* | regexp63 = prior_term[%d]* | profession | pronunciation | rank | rank_label | relations | relatives | religion | residence | resting_place | resting_place_coordinates | restingplace | restingplacecoordinates | regexp64 = riding[%d]* | runningmate | salary | serviceyears | serviceyears_label | signature | signature_alt | signature_size | smallimage | smallimage_alt | source | speaker | speaker_office | spouse | spouses | spouse(s) | regexp65 = state[%d]* | regexp66 = state_assembly[%d]* | regexp67 = state_delegate[%d]* | regexp68 = state_house[%d]* | regexp69 = state_legislature[%d]* | regexp70 = state_senate[%d]* | regexp71 = status[%d]* | regexp72 = suboffice[%d]* | regexp73 = subterm[%d]* | regexp74 = succeeded[%d]* | regexp75 = succeeding[%d]* | regexp76 = successor[%d]* | regexp77 = taoiseach[%d]* | regexp78 = term[%d]* | regexp79 = term_end[%d]* | regexp80 = term_label[%d]* | regexp81 = term_start[%d]* | regexp82 = termend[%d]* | regexp83 = termlabel[%d]* | regexp84 = termstart[%d]* | regexp85 = title[%d]* | unit | unit_label | regexp86 = vicegovernor[%d]* | regexp87 = vicepremier[%d]* | regexp88 = vicepresident[%d]* | regexp89 = viceprimeminister[%d]* | regexp90 = assuming[%d]* | wars | website | width | year | ความสูง | ส่วนสูง }}<noinclude> {{คู่มือการใช้งาน}} </noinclude> 0236de4b11eb3b2345ca3fb4183cd551a6f358d4 อนาวิน สุขเกษมอดิศักดิ์ 0 2 60 48 2023-10-05T12:21:21Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = Anavin Sukkasem-Adisak (2 August 2023).png | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[สภานิติบัญญัติแห่งชาติ|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start1 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | term_end1 = | parliamentarygroup1 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office2 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = พ.ศ. 2566 | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2020|3|14|2023|9|15}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = {{วันเกิด-อายุ|2523|9|5}} | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย a5763380b6e748ca2d8a6a43253198b81e982ddc แม่แบบ:อายุปีและวัน 10 35 61 2023-10-05T12:26:04Z PeachFullzZ 2 สร้างหน้าด้วย "<includeonly>{{อายุปีและวัน/ปี|{{age | {{{1}}} | {{{2}}} | {{{3}}} | {{{4|{{CURRENTYEAR}}}}} | {{{5|{{CURRENTMONTH}}}}} | {{{6|{{CURRENTDAY}}}}}}}}} {{อายุปีและวัน/วัน|{{age in days| {{#ifexpr: {{{5|{{CURRENTMONTH}}}}}<{{{2}}} | {{#expr:{{{4|{{CURRENTYEAR}}}}}-1}} | {{#ifexpr:{{{5|{{CURRENTMONTH}}}}}={{{2}}} | {{#ifexpr:{{{6|{{CURRENTDAY}}}}}<{{{3}}} | {{#expr:{{{4|{{CURRENTYEAR}}}}}-1}} | {{..." wikitext text/x-wiki <includeonly>{{อายุปีและวัน/ปี|{{age | {{{1}}} | {{{2}}} | {{{3}}} | {{{4|{{CURRENTYEAR}}}}} | {{{5|{{CURRENTMONTH}}}}} | {{{6|{{CURRENTDAY}}}}}}}}} {{อายุปีและวัน/วัน|{{age in days| {{#ifexpr: {{{5|{{CURRENTMONTH}}}}}<{{{2}}} | {{#expr:{{{4|{{CURRENTYEAR}}}}}-1}} | {{#ifexpr:{{{5|{{CURRENTMONTH}}}}}={{{2}}} | {{#ifexpr:{{{6|{{CURRENTDAY}}}}}<{{{3}}} | {{#expr:{{{4|{{CURRENTYEAR}}}}}-1}} | {{{4|{{CURRENTYEAR}}}}}}} | {{{4|{{CURRENTYEAR}}}}}}}}} | {{{2}}} | {{{3}}} | {{{4|{{CURRENTYEAR}}}}} | {{{5|{{CURRENTMONTH}}}}} | {{{6|{{CURRENTDAY}}}}}}}}}</includeonly><noinclude>{{Documentation}}</noinclude> 85174c1cef14ebc3198c819023ece175c963a161 แม่แบบ:อายุปีและวัน/ปี 10 36 62 2023-10-05T12:27:15Z PeachFullzZ 2 สร้างหน้าด้วย "{{nts|{{{1}}}}} {{#ifeq: {{{1}}}|1|ปี|ปี}}" wikitext text/x-wiki {{nts|{{{1}}}}} {{#ifeq: {{{1}}}|1|ปี|ปี}} 402f20f30309fb50ada955d95502e147e59434c1 แม่แบบ:Nts 10 37 63 2023-10-05T12:28:35Z PeachFullzZ 2 เปลี่ยนทางหน้าไปยัง [[แม่แบบ:Number table sorting]] wikitext text/x-wiki #เปลี่ยนทาง [[แม่แบบ:Number table sorting]] e6a350ffb95337ecce58a3ecf51a79f5c4fc05b7 แม่แบบ:Number table sorting 10 38 64 2023-10-05T12:28:57Z PeachFullzZ 2 สร้างหน้าด้วย "<includeonly>{{#invoke:Number table sorting|main}}</includeonly><noinclude> {{documentation}} <!-- Add categories to the /doc subpage; interwikis go to Wikidata, thank you! --> </noinclude>" wikitext text/x-wiki <includeonly>{{#invoke:Number table sorting|main}}</includeonly><noinclude> {{documentation}} <!-- Add categories to the /doc subpage; interwikis go to Wikidata, thank you! --> </noinclude> b02dca5537a7cd60a2fabf4a3b0563e3b96a4dd9 มอดูล:Number table sorting 828 39 65 2023-10-05T12:30:21Z PeachFullzZ 2 สร้างหน้าด้วย "local lang = mw.language.getContentLanguage() local Math = require('Module:Math') local SortKey = require('Module:Sortkey') -- constants local INF = math.huge local NEGINF = -math.huge local MINUS = '−' -- Unicode U+2212 MINUS SIGN (UTF-8: e2 88 92) -------------------------------------------------------------------------------- -- Nts class -------------------------------------------------------------------------------- local Nts = {} Nts.__in..." Scribunto text/plain local lang = mw.language.getContentLanguage() local Math = require('Module:Math') local SortKey = require('Module:Sortkey') -- constants local INF = math.huge local NEGINF = -math.huge local MINUS = '−' -- Unicode U+2212 MINUS SIGN (UTF-8: e2 88 92) -------------------------------------------------------------------------------- -- Nts class -------------------------------------------------------------------------------- local Nts = {} Nts.__index = Nts Nts.formats = { no = true, yes = true, } function Nts.new(args) local self = setmetatable({}, Nts) self:parseNumber(args[1]) -- Set the format string self.format = args.format or 'yes' if not Nts.formats[self.format] then error(string.format( "'%s' is not a valid format", tostring(self.format) ), 0) end -- To display some text before the display version of the number -- {{nts|123456789.00123|prefix=approx.&nbsp;}} → approx. 123,456,789.00123 self.prefix = args.prefix or '' -- debug info self.debug = args.debug or 'no' self.quiet = args.quiet or 'no' return self end -- Parse the entered number function Nts:parseNumber(s) -- sanitize s = s or ''; s = string.gsub(s,'&minus;','-') s = string.gsub(s, MINUS, '-') self.rawNumberString = s -- fractions. was somewhat but completely broken at some point self.isFraction = (string.find(s, '/') ~= nil) if self.isFraction then error(string.format( "Fractions are not supported", tostring(s) ), 0) end -- format detection self.isScientificNotation = (string.find(s, 'e') ~= nil) -- parse with language options self.number = lang:parseFormattedNumber(s) -- parse with fallback if not self.number then self.number = tonumber(s) end -- allow for empty string as a value if not self.number then -- error(string.format( -- "'%s' is not a valid number", -- tostring(s) -- ), 0) self.number = NEGINF end if self.number < 0 then self.sign = MINUS else self.sign = '' end self.absNumber = math.abs(self.number) if self.absNumber ~= INF then self.magnitude = math.floor(math.log10(self.absNumber)) self.significand = self.number / 10^self.magnitude self.precision = Math._precision(self.rawNumberString) self.integer = math.floor(self.absNumber) self.fractional = math.abs(self.number - self.integer) end end function Nts:makeDisplay() local ret ={} if self.quiet == 'yes' then return '' end ret[#ret + 1] = self.prefix local sciNotation = string.find(tostring(self.number),'e') if self.absNnumber == INF or isNaN(self.number) or self.magnitude ==nil or math.abs(self.magnitude) == INF then ret[#ret + 1] = string.gsub(self.rawNumberString, '-', MINUS) elseif sciNotation ~= nil or math.abs(self.magnitude) >= 9 then ret[#ret + 1] = self.sign if self.format == 'yes' then ret[#ret + 1] = lang:formatNum(math.abs(self.number * 10^-self.magnitude)) else ret[#ret + 1] = math.abs(self.number * 10^-self.magnitude) end ret[#ret + 1] = '<span style="margin-left:0.2em">×<span style="margin-left:0.1em">10</span></span><s style="display:none">^</s><sup>' if self.magnitude<0 then ret[#ret + 1] = MINUS .. (-self.magnitude) else ret[#ret + 1] = self.magnitude end ret[#ret + 1] = '</sup>' else ret[#ret + 1] = self.sign if self.format == 'yes' then ret[#ret + 1] = Math._precision_format(self.absNumber, self.precision) else local newPrecision = Math._precision(self.absNumber) ret[#ret + 1] = tostring(self.absNumber) if newPrecision < self.precision then if self.integer == self.absNumber then ret[#ret + 1] = '.' end ret[#ret + 1] = string.rep('0', math.min(12, self.precision - newPrecision) ) end end end return table.concat(ret) end function Nts:makeSortKey() return SortKey._sortKeyForNumber(self.number) .. '♠' end function ifNaNThen(n,p) if isNaN(n) then return p end return n end function isNaN(n) return n ~= n end function Nts:renderTrackingCategories() if self.hasDeprecatedParameters then return '[[Category:Nts templates with deprecated parameters]]' else return '' end end function Nts:__tostring() local root = mw.html.create() local span = root:tag('span') :attr('data-sort-value', self:makeSortKey()) if self.debug == 'yes' then span:tag('span') :css('border', '1px solid') :wikitext(self:makeSortKey()) elseif self.quiet ~= 'no' then span:css('display', 'none') end -- Display if self.quiet == 'no' then span:wikitext(self:makeDisplay()) end -- Tracking categories root:wikitext(self:renderTrackingCategories()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() return { Nts = Nts } end function p._main(args) local success, ret = pcall(function () local nts = Nts.new(args) return tostring(nts) end) if success then return ret else ret = string.format( '<strong class="error">Error in [[Template:Nts]]: %s</strong>', ret ) if mw.title.getCurrentTitle().namespace == 0 then -- Only categorise in the main namespace ret = ret .. '[[Category:Nts templates with errors]]' end return ret end end function p.main(frame) local args = require('Module:Arguments').getArgs(frame, { wrappers = { 'Template:Number table sorting' }, }) return p._main(args) end return p 75e3ee364d55769c258d028450e8f01480fb6004 66 65 2023-10-05T12:30:41Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Number table sorting]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local lang = mw.language.getContentLanguage() local Math = require('Module:Math') local SortKey = require('Module:Sortkey') -- constants local INF = math.huge local NEGINF = -math.huge local MINUS = '−' -- Unicode U+2212 MINUS SIGN (UTF-8: e2 88 92) -------------------------------------------------------------------------------- -- Nts class -------------------------------------------------------------------------------- local Nts = {} Nts.__index = Nts Nts.formats = { no = true, yes = true, } function Nts.new(args) local self = setmetatable({}, Nts) self:parseNumber(args[1]) -- Set the format string self.format = args.format or 'yes' if not Nts.formats[self.format] then error(string.format( "'%s' is not a valid format", tostring(self.format) ), 0) end -- To display some text before the display version of the number -- {{nts|123456789.00123|prefix=approx.&nbsp;}} → approx. 123,456,789.00123 self.prefix = args.prefix or '' -- debug info self.debug = args.debug or 'no' self.quiet = args.quiet or 'no' return self end -- Parse the entered number function Nts:parseNumber(s) -- sanitize s = s or ''; s = string.gsub(s,'&minus;','-') s = string.gsub(s, MINUS, '-') self.rawNumberString = s -- fractions. was somewhat but completely broken at some point self.isFraction = (string.find(s, '/') ~= nil) if self.isFraction then error(string.format( "Fractions are not supported", tostring(s) ), 0) end -- format detection self.isScientificNotation = (string.find(s, 'e') ~= nil) -- parse with language options self.number = lang:parseFormattedNumber(s) -- parse with fallback if not self.number then self.number = tonumber(s) end -- allow for empty string as a value if not self.number then -- error(string.format( -- "'%s' is not a valid number", -- tostring(s) -- ), 0) self.number = NEGINF end if self.number < 0 then self.sign = MINUS else self.sign = '' end self.absNumber = math.abs(self.number) if self.absNumber ~= INF then self.magnitude = math.floor(math.log10(self.absNumber)) self.significand = self.number / 10^self.magnitude self.precision = Math._precision(self.rawNumberString) self.integer = math.floor(self.absNumber) self.fractional = math.abs(self.number - self.integer) end end function Nts:makeDisplay() local ret ={} if self.quiet == 'yes' then return '' end ret[#ret + 1] = self.prefix local sciNotation = string.find(tostring(self.number),'e') if self.absNnumber == INF or isNaN(self.number) or self.magnitude ==nil or math.abs(self.magnitude) == INF then ret[#ret + 1] = string.gsub(self.rawNumberString, '-', MINUS) elseif sciNotation ~= nil or math.abs(self.magnitude) >= 9 then ret[#ret + 1] = self.sign if self.format == 'yes' then ret[#ret + 1] = lang:formatNum(math.abs(self.number * 10^-self.magnitude)) else ret[#ret + 1] = math.abs(self.number * 10^-self.magnitude) end ret[#ret + 1] = '<span style="margin-left:0.2em">×<span style="margin-left:0.1em">10</span></span><s style="display:none">^</s><sup>' if self.magnitude<0 then ret[#ret + 1] = MINUS .. (-self.magnitude) else ret[#ret + 1] = self.magnitude end ret[#ret + 1] = '</sup>' else ret[#ret + 1] = self.sign if self.format == 'yes' then ret[#ret + 1] = Math._precision_format(self.absNumber, self.precision) else local newPrecision = Math._precision(self.absNumber) ret[#ret + 1] = tostring(self.absNumber) if newPrecision < self.precision then if self.integer == self.absNumber then ret[#ret + 1] = '.' end ret[#ret + 1] = string.rep('0', math.min(12, self.precision - newPrecision) ) end end end return table.concat(ret) end function Nts:makeSortKey() return SortKey._sortKeyForNumber(self.number) .. '♠' end function ifNaNThen(n,p) if isNaN(n) then return p end return n end function isNaN(n) return n ~= n end function Nts:renderTrackingCategories() if self.hasDeprecatedParameters then return '[[Category:Nts templates with deprecated parameters]]' else return '' end end function Nts:__tostring() local root = mw.html.create() local span = root:tag('span') :attr('data-sort-value', self:makeSortKey()) if self.debug == 'yes' then span:tag('span') :css('border', '1px solid') :wikitext(self:makeSortKey()) elseif self.quiet ~= 'no' then span:css('display', 'none') end -- Display if self.quiet == 'no' then span:wikitext(self:makeDisplay()) end -- Tracking categories root:wikitext(self:renderTrackingCategories()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() return { Nts = Nts } end function p._main(args) local success, ret = pcall(function () local nts = Nts.new(args) return tostring(nts) end) if success then return ret else ret = string.format( '<strong class="error">Error in [[Template:Nts]]: %s</strong>', ret ) if mw.title.getCurrentTitle().namespace == 0 then -- Only categorise in the main namespace ret = ret .. '[[Category:Nts templates with errors]]' end return ret end end function p.main(frame) local args = require('Module:Arguments').getArgs(frame, { wrappers = { 'Template:Number table sorting' }, }) return p._main(args) end return p 75e3ee364d55769c258d028450e8f01480fb6004 มอดูล:Math 828 40 67 2023-10-05T12:31:38Z PeachFullzZ 2 สร้างหน้าด้วย "--[[ This module provides a number of basic mathematical operations. ]] local yesno, getArgs -- lazily initialized local p = {} -- Holds functions to be returned from #invoke, and functions to make available to other Lua modules. local wrap = {} -- Holds wrapper functions that process arguments from #invoke. These act as intemediary between functions meant for #invoke and functions meant for Lua. --[[ Helper functions used to avoid redundant co..." Scribunto text/plain --[[ This module provides a number of basic mathematical operations. ]] local yesno, getArgs -- lazily initialized local p = {} -- Holds functions to be returned from #invoke, and functions to make available to other Lua modules. local wrap = {} -- Holds wrapper functions that process arguments from #invoke. These act as intemediary between functions meant for #invoke and functions meant for Lua. --[[ Helper functions used to avoid redundant code. ]] local function err(msg) -- Generates wikitext error messages. return mw.ustring.format('<strong class="error">Formatting error: %s</strong>', msg) end local function unpackNumberArgs(args) -- Returns an unpacked list of arguments specified with numerical keys. local ret = {} for k, v in pairs(args) do if type(k) == 'number' then table.insert(ret, v) end end return unpack(ret) end local function makeArgArray(...) -- Makes an array of arguments from a list of arguments that might include nils. local args = {...} -- Table of arguments. It might contain nils or non-number values, so we can't use ipairs. local nums = {} -- Stores the numbers of valid numerical arguments. local ret = {} for k, v in pairs(args) do v = p._cleanNumber(v) if v then nums[#nums + 1] = k args[k] = v end end table.sort(nums) for i, num in ipairs(nums) do ret[#ret + 1] = args[num] end return ret end local function fold(func, ...) -- Use a function on all supplied arguments, and return the result. The function must accept two numbers as parameters, -- and must return a number as an output. This number is then supplied as input to the next function call. local vals = makeArgArray(...) local count = #vals -- The number of valid arguments if count == 0 then return -- Exit if we have no valid args, otherwise removing the first arg would cause an error. nil, 0 end local ret = table.remove(vals, 1) for _, val in ipairs(vals) do ret = func(ret, val) end return ret, count end --[[ Fold arguments by selectively choosing values (func should return when to choose the current "dominant" value). ]] local function binary_fold(func, ...) local value = fold((function(a, b) if func(a, b) then return a else return b end end), ...) return value end --[[ random Generate a random number Usage: {{#invoke: Math | random }} {{#invoke: Math | random | maximum value }} {{#invoke: Math | random | minimum value | maximum value }} ]] function wrap.random(args) local first = p._cleanNumber(args[1]) local second = p._cleanNumber(args[2]) return p._random(first, second) end function p._random(first, second) math.randomseed(mw.site.stats.edits + mw.site.stats.pages + os.time() + math.floor(os.clock() * 1000000000)) -- math.random will throw an error if given an explicit nil parameter, so we need to use if statements to check the params. if first and second then if first <= second then -- math.random doesn't allow the first number to be greater than the second. return math.random(first, second) end elseif first then return math.random(first) else return math.random() end end --[[ order Determine order of magnitude of a number Usage: {{#invoke: Math | order | value }} ]] function wrap.order(args) local input_string = (args[1] or args.x or '0'); local input_number = p._cleanNumber(input_string); if input_number == nil then return err('order of magnitude input appears non-numeric') else return p._order(input_number) end end function p._order(x) if x == 0 then return 0 end return math.floor(math.log10(math.abs(x))) end --[[ precision Detemines the precision of a number using the string representation Usage: {{ #invoke: Math | precision | value }} ]] function wrap.precision(args) local input_string = (args[1] or args.x or '0'); local trap_fraction = args.check_fraction; local input_number; if not yesno then yesno = require('Module:Yesno') end if yesno(trap_fraction, true) then -- Returns true for all input except nil, false, "no", "n", "0" and a few others. See [[Module:Yesno]]. local pos = string.find(input_string, '/', 1, true); if pos ~= nil then if string.find(input_string, '/', pos + 1, true) == nil then local denominator = string.sub(input_string, pos+1, -1); local denom_value = tonumber(denominator); if denom_value ~= nil then return math.log10(denom_value); end end end end input_number, input_string = p._cleanNumber(input_string); if input_string == nil then return err('precision input appears non-numeric') else return p._precision(input_string) end end function p._precision(x) if type(x) == 'number' then x = tostring(x) end x = string.upper(x) local decimal = x:find('%.') local exponent_pos = x:find('E') local result = 0; if exponent_pos ~= nil then local exponent = string.sub(x, exponent_pos + 1) x = string.sub(x, 1, exponent_pos - 1) result = result - tonumber(exponent) end if decimal ~= nil then result = result + string.len(x) - decimal return result end local pos = string.len(x); while x:byte(pos) == string.byte('0') do pos = pos - 1 result = result - 1 if pos <= 0 then return 0 end end return result end --[[ max Finds the maximum argument Usage: {{#invoke:Math| max | value1 | value2 | ... }} Note, any values that do not evaluate to numbers are ignored. ]] function wrap.max(args) return p._max(unpackNumberArgs(args)) end function p._max(...) local max_value = binary_fold((function(a, b) return a > b end), ...) if max_value then return max_value end end --[[ median Find the median of set of numbers Usage: {{#invoke:Math | median | number1 | number2 | ...}} OR {{#invoke:Math | median }} ]] function wrap.median(args) return p._median(unpackNumberArgs(args)) end function p._median(...) local vals = makeArgArray(...) local count = #vals table.sort(vals) if count == 0 then return 0 end if p._mod(count, 2) == 0 then return (vals[count/2] + vals[count/2+1])/2 else return vals[math.ceil(count/2)] end end --[[ min Finds the minimum argument Usage: {{#invoke:Math| min | value1 | value2 | ... }} OR {{#invoke:Math| min }} When used with no arguments, it takes its input from the parent frame. Note, any values that do not evaluate to numbers are ignored. ]] function wrap.min(args) return p._min(unpackNumberArgs(args)) end function p._min(...) local min_value = binary_fold((function(a, b) return a < b end), ...) if min_value then return min_value end end --[[ sum Finds the sum Usage: {{#invoke:Math| sum | value1 | value2 | ... }} OR {{#invoke:Math| sum }} Note, any values that do not evaluate to numbers are ignored. ]] function wrap.sum(args) return p._sum(unpackNumberArgs(args)) end function p._sum(...) local sums, count = fold((function(a, b) return a + b end), ...) if not sums then return 0 else return sums end end --[[ average Finds the average Usage: {{#invoke:Math| average | value1 | value2 | ... }} OR {{#invoke:Math| average }} Note, any values that do not evaluate to numbers are ignored. ]] function wrap.average(args) return p._average(unpackNumberArgs(args)) end function p._average(...) local sum, count = fold((function(a, b) return a + b end), ...) if not sum then return 0 else return sum / count end end --[[ round Rounds a number to specified precision Usage: {{#invoke:Math | round | value | precision }} --]] function wrap.round(args) local value = p._cleanNumber(args[1] or args.value or 0) local precision = p._cleanNumber(args[2] or args.precision or 0) if value == nil or precision == nil then return err('round input appears non-numeric') else return p._round(value, precision) end end function p._round(value, precision) local rescale = math.pow(10, precision or 0); return math.floor(value * rescale + 0.5) / rescale; end --[[ log10 returns the log (base 10) of a number Usage: {{#invoke:Math | log10 | x }} ]] function wrap.log10(args) return math.log10(args[1]) end --[[ mod Implements the modulo operator Usage: {{#invoke:Math | mod | x | y }} --]] function wrap.mod(args) local x = p._cleanNumber(args[1]) local y = p._cleanNumber(args[2]) if not x then return err('first argument to mod appears non-numeric') elseif not y then return err('second argument to mod appears non-numeric') else return p._mod(x, y) end end function p._mod(x, y) local ret = x % y if not (0 <= ret and ret < y) then ret = 0 end return ret end --[[ gcd Calculates the greatest common divisor of multiple numbers Usage: {{#invoke:Math | gcd | value 1 | value 2 | value 3 | ... }} --]] function wrap.gcd(args) return p._gcd(unpackNumberArgs(args)) end function p._gcd(...) local function findGcd(a, b) local r = b local oldr = a while r ~= 0 do local quotient = math.floor(oldr / r) oldr, r = r, oldr - quotient * r end if oldr < 0 then oldr = oldr * -1 end return oldr end local result, count = fold(findGcd, ...) return result end --[[ precision_format Rounds a number to the specified precision and formats according to rules originally used for {{template:Rnd}}. Output is a string. Usage: {{#invoke: Math | precision_format | number | precision }} ]] function wrap.precision_format(args) local value_string = args[1] or 0 local precision = args[2] or 0 return p._precision_format(value_string, precision) end function p._precision_format(value_string, precision) -- For access to Mediawiki built-in formatter. local lang = mw.getContentLanguage(); local value value, value_string = p._cleanNumber(value_string) precision = p._cleanNumber(precision) -- Check for non-numeric input if value == nil or precision == nil then return err('invalid input when rounding') end local current_precision = p._precision(value) local order = p._order(value) -- Due to round-off effects it is neccesary to limit the returned precision under -- some circumstances because the terminal digits will be inaccurately reported. if order + precision >= 14 then if order + p._precision(value_string) >= 14 then precision = 13 - order; end end -- If rounding off, truncate extra digits if precision < current_precision then value = p._round(value, precision) current_precision = p._precision(value) end local formatted_num = lang:formatNum(math.abs(value)) local sign -- Use proper unary minus sign rather than ASCII default if value < 0 then sign = '−' else sign = '' end -- Handle cases requiring scientific notation if string.find(formatted_num, 'E', 1, true) ~= nil or math.abs(order) >= 9 then value = value * math.pow(10, -order) current_precision = current_precision + order precision = precision + order formatted_num = lang:formatNum(math.abs(value)) else order = 0; end formatted_num = sign .. formatted_num -- Pad with zeros, if needed if current_precision < precision then local padding if current_precision <= 0 then if precision > 0 then local zero_sep = lang:formatNum(1.1) formatted_num = formatted_num .. zero_sep:sub(2,2) padding = precision if padding > 20 then padding = 20 end formatted_num = formatted_num .. string.rep('0', padding) end else padding = precision - current_precision if padding > 20 then padding = 20 end formatted_num = formatted_num .. string.rep('0', padding) end end -- Add exponential notation, if necessary. if order ~= 0 then -- Use proper unary minus sign rather than ASCII default if order < 0 then order = '−' .. lang:formatNum(math.abs(order)) else order = lang:formatNum(order) end formatted_num = formatted_num .. '<span style="margin:0 .15em 0 .25em">×</span>10<sup>' .. order .. '</sup>' end return formatted_num end --[[ divide Implements the division operator Usage: {{#invoke:Math | divide | x | y | round= | precision= }} --]] function wrap.divide(args) local x = args[1] local y = args[2] local round = args.round local precision = args.precision if not yesno then yesno = require('Module:Yesno') end return p._divide(x, y, yesno(round), precision) end function p._divide(x, y, round, precision) if y == nil or y == "" then return err("Empty divisor") elseif not tonumber(y) then if type(y) == 'string' and string.sub(y, 1, 1) == '<' then return y else return err("Not a number: " .. y) end elseif x == nil or x == "" then return err("Empty dividend") elseif not tonumber(x) then if type(x) == 'string' and string.sub(x, 1, 1) == '<' then return x else return err("Not a number: " .. x) end else local z = x / y if round then return p._round(z, 0) elseif precision then return p._round(z, precision) else return z end end end --[[ Helper function that interprets the input numerically. If the input does not appear to be a number, attempts evaluating it as a parser functions expression. ]] function p._cleanNumber(number_string) if type(number_string) == 'number' then -- We were passed a number, so we don't need to do any processing. return number_string, tostring(number_string) elseif type(number_string) ~= 'string' or not number_string:find('%S') then -- We were passed a non-string or a blank string, so exit. return nil, nil; end -- Attempt basic conversion local number = tonumber(number_string) -- If failed, attempt to evaluate input as an expression if number == nil then local success, result = pcall(mw.ext.ParserFunctions.expr, number_string) if success then number = tonumber(result) number_string = tostring(number) else number = nil number_string = nil end else number_string = number_string:match("^%s*(.-)%s*$") -- String is valid but may contain padding, clean it. number_string = number_string:match("^%+(.*)$") or number_string -- Trim any leading + signs. if number_string:find('^%-?0[xX]') then -- Number is using 0xnnn notation to indicate base 16; use the number that Lua detected instead. number_string = tostring(number) end end return number, number_string end --[[ Wrapper function that does basic argument processing. This ensures that all functions from #invoke can use either the current frame or the parent frame, and it also trims whitespace for all arguments and removes blank arguments. ]] local mt = { __index = function(t, k) return function(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return wrap[k](getArgs(frame)) -- Argument processing is left to Module:Arguments. Whitespace is trimmed and blank arguments are removed. end end } return setmetatable(p, mt) 2bbe734d898299f65412963a3c1782e9fcc4d9ca 68 67 2023-10-05T12:31:51Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Math]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain --[[ This module provides a number of basic mathematical operations. ]] local yesno, getArgs -- lazily initialized local p = {} -- Holds functions to be returned from #invoke, and functions to make available to other Lua modules. local wrap = {} -- Holds wrapper functions that process arguments from #invoke. These act as intemediary between functions meant for #invoke and functions meant for Lua. --[[ Helper functions used to avoid redundant code. ]] local function err(msg) -- Generates wikitext error messages. return mw.ustring.format('<strong class="error">Formatting error: %s</strong>', msg) end local function unpackNumberArgs(args) -- Returns an unpacked list of arguments specified with numerical keys. local ret = {} for k, v in pairs(args) do if type(k) == 'number' then table.insert(ret, v) end end return unpack(ret) end local function makeArgArray(...) -- Makes an array of arguments from a list of arguments that might include nils. local args = {...} -- Table of arguments. It might contain nils or non-number values, so we can't use ipairs. local nums = {} -- Stores the numbers of valid numerical arguments. local ret = {} for k, v in pairs(args) do v = p._cleanNumber(v) if v then nums[#nums + 1] = k args[k] = v end end table.sort(nums) for i, num in ipairs(nums) do ret[#ret + 1] = args[num] end return ret end local function fold(func, ...) -- Use a function on all supplied arguments, and return the result. The function must accept two numbers as parameters, -- and must return a number as an output. This number is then supplied as input to the next function call. local vals = makeArgArray(...) local count = #vals -- The number of valid arguments if count == 0 then return -- Exit if we have no valid args, otherwise removing the first arg would cause an error. nil, 0 end local ret = table.remove(vals, 1) for _, val in ipairs(vals) do ret = func(ret, val) end return ret, count end --[[ Fold arguments by selectively choosing values (func should return when to choose the current "dominant" value). ]] local function binary_fold(func, ...) local value = fold((function(a, b) if func(a, b) then return a else return b end end), ...) return value end --[[ random Generate a random number Usage: {{#invoke: Math | random }} {{#invoke: Math | random | maximum value }} {{#invoke: Math | random | minimum value | maximum value }} ]] function wrap.random(args) local first = p._cleanNumber(args[1]) local second = p._cleanNumber(args[2]) return p._random(first, second) end function p._random(first, second) math.randomseed(mw.site.stats.edits + mw.site.stats.pages + os.time() + math.floor(os.clock() * 1000000000)) -- math.random will throw an error if given an explicit nil parameter, so we need to use if statements to check the params. if first and second then if first <= second then -- math.random doesn't allow the first number to be greater than the second. return math.random(first, second) end elseif first then return math.random(first) else return math.random() end end --[[ order Determine order of magnitude of a number Usage: {{#invoke: Math | order | value }} ]] function wrap.order(args) local input_string = (args[1] or args.x or '0'); local input_number = p._cleanNumber(input_string); if input_number == nil then return err('order of magnitude input appears non-numeric') else return p._order(input_number) end end function p._order(x) if x == 0 then return 0 end return math.floor(math.log10(math.abs(x))) end --[[ precision Detemines the precision of a number using the string representation Usage: {{ #invoke: Math | precision | value }} ]] function wrap.precision(args) local input_string = (args[1] or args.x or '0'); local trap_fraction = args.check_fraction; local input_number; if not yesno then yesno = require('Module:Yesno') end if yesno(trap_fraction, true) then -- Returns true for all input except nil, false, "no", "n", "0" and a few others. See [[Module:Yesno]]. local pos = string.find(input_string, '/', 1, true); if pos ~= nil then if string.find(input_string, '/', pos + 1, true) == nil then local denominator = string.sub(input_string, pos+1, -1); local denom_value = tonumber(denominator); if denom_value ~= nil then return math.log10(denom_value); end end end end input_number, input_string = p._cleanNumber(input_string); if input_string == nil then return err('precision input appears non-numeric') else return p._precision(input_string) end end function p._precision(x) if type(x) == 'number' then x = tostring(x) end x = string.upper(x) local decimal = x:find('%.') local exponent_pos = x:find('E') local result = 0; if exponent_pos ~= nil then local exponent = string.sub(x, exponent_pos + 1) x = string.sub(x, 1, exponent_pos - 1) result = result - tonumber(exponent) end if decimal ~= nil then result = result + string.len(x) - decimal return result end local pos = string.len(x); while x:byte(pos) == string.byte('0') do pos = pos - 1 result = result - 1 if pos <= 0 then return 0 end end return result end --[[ max Finds the maximum argument Usage: {{#invoke:Math| max | value1 | value2 | ... }} Note, any values that do not evaluate to numbers are ignored. ]] function wrap.max(args) return p._max(unpackNumberArgs(args)) end function p._max(...) local max_value = binary_fold((function(a, b) return a > b end), ...) if max_value then return max_value end end --[[ median Find the median of set of numbers Usage: {{#invoke:Math | median | number1 | number2 | ...}} OR {{#invoke:Math | median }} ]] function wrap.median(args) return p._median(unpackNumberArgs(args)) end function p._median(...) local vals = makeArgArray(...) local count = #vals table.sort(vals) if count == 0 then return 0 end if p._mod(count, 2) == 0 then return (vals[count/2] + vals[count/2+1])/2 else return vals[math.ceil(count/2)] end end --[[ min Finds the minimum argument Usage: {{#invoke:Math| min | value1 | value2 | ... }} OR {{#invoke:Math| min }} When used with no arguments, it takes its input from the parent frame. Note, any values that do not evaluate to numbers are ignored. ]] function wrap.min(args) return p._min(unpackNumberArgs(args)) end function p._min(...) local min_value = binary_fold((function(a, b) return a < b end), ...) if min_value then return min_value end end --[[ sum Finds the sum Usage: {{#invoke:Math| sum | value1 | value2 | ... }} OR {{#invoke:Math| sum }} Note, any values that do not evaluate to numbers are ignored. ]] function wrap.sum(args) return p._sum(unpackNumberArgs(args)) end function p._sum(...) local sums, count = fold((function(a, b) return a + b end), ...) if not sums then return 0 else return sums end end --[[ average Finds the average Usage: {{#invoke:Math| average | value1 | value2 | ... }} OR {{#invoke:Math| average }} Note, any values that do not evaluate to numbers are ignored. ]] function wrap.average(args) return p._average(unpackNumberArgs(args)) end function p._average(...) local sum, count = fold((function(a, b) return a + b end), ...) if not sum then return 0 else return sum / count end end --[[ round Rounds a number to specified precision Usage: {{#invoke:Math | round | value | precision }} --]] function wrap.round(args) local value = p._cleanNumber(args[1] or args.value or 0) local precision = p._cleanNumber(args[2] or args.precision or 0) if value == nil or precision == nil then return err('round input appears non-numeric') else return p._round(value, precision) end end function p._round(value, precision) local rescale = math.pow(10, precision or 0); return math.floor(value * rescale + 0.5) / rescale; end --[[ log10 returns the log (base 10) of a number Usage: {{#invoke:Math | log10 | x }} ]] function wrap.log10(args) return math.log10(args[1]) end --[[ mod Implements the modulo operator Usage: {{#invoke:Math | mod | x | y }} --]] function wrap.mod(args) local x = p._cleanNumber(args[1]) local y = p._cleanNumber(args[2]) if not x then return err('first argument to mod appears non-numeric') elseif not y then return err('second argument to mod appears non-numeric') else return p._mod(x, y) end end function p._mod(x, y) local ret = x % y if not (0 <= ret and ret < y) then ret = 0 end return ret end --[[ gcd Calculates the greatest common divisor of multiple numbers Usage: {{#invoke:Math | gcd | value 1 | value 2 | value 3 | ... }} --]] function wrap.gcd(args) return p._gcd(unpackNumberArgs(args)) end function p._gcd(...) local function findGcd(a, b) local r = b local oldr = a while r ~= 0 do local quotient = math.floor(oldr / r) oldr, r = r, oldr - quotient * r end if oldr < 0 then oldr = oldr * -1 end return oldr end local result, count = fold(findGcd, ...) return result end --[[ precision_format Rounds a number to the specified precision and formats according to rules originally used for {{template:Rnd}}. Output is a string. Usage: {{#invoke: Math | precision_format | number | precision }} ]] function wrap.precision_format(args) local value_string = args[1] or 0 local precision = args[2] or 0 return p._precision_format(value_string, precision) end function p._precision_format(value_string, precision) -- For access to Mediawiki built-in formatter. local lang = mw.getContentLanguage(); local value value, value_string = p._cleanNumber(value_string) precision = p._cleanNumber(precision) -- Check for non-numeric input if value == nil or precision == nil then return err('invalid input when rounding') end local current_precision = p._precision(value) local order = p._order(value) -- Due to round-off effects it is neccesary to limit the returned precision under -- some circumstances because the terminal digits will be inaccurately reported. if order + precision >= 14 then if order + p._precision(value_string) >= 14 then precision = 13 - order; end end -- If rounding off, truncate extra digits if precision < current_precision then value = p._round(value, precision) current_precision = p._precision(value) end local formatted_num = lang:formatNum(math.abs(value)) local sign -- Use proper unary minus sign rather than ASCII default if value < 0 then sign = '−' else sign = '' end -- Handle cases requiring scientific notation if string.find(formatted_num, 'E', 1, true) ~= nil or math.abs(order) >= 9 then value = value * math.pow(10, -order) current_precision = current_precision + order precision = precision + order formatted_num = lang:formatNum(math.abs(value)) else order = 0; end formatted_num = sign .. formatted_num -- Pad with zeros, if needed if current_precision < precision then local padding if current_precision <= 0 then if precision > 0 then local zero_sep = lang:formatNum(1.1) formatted_num = formatted_num .. zero_sep:sub(2,2) padding = precision if padding > 20 then padding = 20 end formatted_num = formatted_num .. string.rep('0', padding) end else padding = precision - current_precision if padding > 20 then padding = 20 end formatted_num = formatted_num .. string.rep('0', padding) end end -- Add exponential notation, if necessary. if order ~= 0 then -- Use proper unary minus sign rather than ASCII default if order < 0 then order = '−' .. lang:formatNum(math.abs(order)) else order = lang:formatNum(order) end formatted_num = formatted_num .. '<span style="margin:0 .15em 0 .25em">×</span>10<sup>' .. order .. '</sup>' end return formatted_num end --[[ divide Implements the division operator Usage: {{#invoke:Math | divide | x | y | round= | precision= }} --]] function wrap.divide(args) local x = args[1] local y = args[2] local round = args.round local precision = args.precision if not yesno then yesno = require('Module:Yesno') end return p._divide(x, y, yesno(round), precision) end function p._divide(x, y, round, precision) if y == nil or y == "" then return err("Empty divisor") elseif not tonumber(y) then if type(y) == 'string' and string.sub(y, 1, 1) == '<' then return y else return err("Not a number: " .. y) end elseif x == nil or x == "" then return err("Empty dividend") elseif not tonumber(x) then if type(x) == 'string' and string.sub(x, 1, 1) == '<' then return x else return err("Not a number: " .. x) end else local z = x / y if round then return p._round(z, 0) elseif precision then return p._round(z, precision) else return z end end end --[[ Helper function that interprets the input numerically. If the input does not appear to be a number, attempts evaluating it as a parser functions expression. ]] function p._cleanNumber(number_string) if type(number_string) == 'number' then -- We were passed a number, so we don't need to do any processing. return number_string, tostring(number_string) elseif type(number_string) ~= 'string' or not number_string:find('%S') then -- We were passed a non-string or a blank string, so exit. return nil, nil; end -- Attempt basic conversion local number = tonumber(number_string) -- If failed, attempt to evaluate input as an expression if number == nil then local success, result = pcall(mw.ext.ParserFunctions.expr, number_string) if success then number = tonumber(result) number_string = tostring(number) else number = nil number_string = nil end else number_string = number_string:match("^%s*(.-)%s*$") -- String is valid but may contain padding, clean it. number_string = number_string:match("^%+(.*)$") or number_string -- Trim any leading + signs. if number_string:find('^%-?0[xX]') then -- Number is using 0xnnn notation to indicate base 16; use the number that Lua detected instead. number_string = tostring(number) end end return number, number_string end --[[ Wrapper function that does basic argument processing. This ensures that all functions from #invoke can use either the current frame or the parent frame, and it also trims whitespace for all arguments and removes blank arguments. ]] local mt = { __index = function(t, k) return function(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return wrap[k](getArgs(frame)) -- Argument processing is left to Module:Arguments. Whitespace is trimmed and blank arguments are removed. end end } return setmetatable(p, mt) 2bbe734d898299f65412963a3c1782e9fcc4d9ca มอดูล:Sortkey 828 41 69 2023-10-05T12:32:38Z PeachFullzZ 2 สร้างหน้าด้วย "local getArgs = require('Module:Arguments').getArgs local p = {} function p._encode(sortkey) -- Protect against sortkey nesting. -- Example: {{sort|{{dts|2013|07|07}}|{{dts|1990|12|01}}}} if string.find(sortkey, "sortkey") or string.find(sortkey, "data-sort-value") then return ""; end return mw.text.encode(sortkey) end function p.encode(frame) local args = getArgs(frame); return p._encode(args[1] or "") end local function valid_numbe..." Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local p = {} function p._encode(sortkey) -- Protect against sortkey nesting. -- Example: {{sort|{{dts|2013|07|07}}|{{dts|1990|12|01}}}} if string.find(sortkey, "sortkey") or string.find(sortkey, "data-sort-value") then return ""; end return mw.text.encode(sortkey) end function p.encode(frame) local args = getArgs(frame); return p._encode(args[1] or "") end local function valid_number(num) -- Return true if num is a valid number. -- In Scribunto (different from some standard Lua), when expressed as a string, -- overflow or other problems are indicated with text like "inf" or "nan" -- which are regarded as invalid here (each contains "n"). if type(num) == 'number' and tostring(num):find('n', 1, true) == nil then return true end end function p._sortKeyForNumber(value) local sortkey if not valid_number(value) then if value < 0 then sortkey = '1000000000000000000' else sortkey = '9000000000000000000' end elseif value == 0 then sortkey = '5000000000000000000' else local mag = math.floor(math.log10(math.abs(value)) + 1e-14) local prefix if value > 0 then prefix = 7000 + mag else prefix = 2999 - mag value = value + 10^(mag+1) end sortkey = string.format('%d', prefix) .. string.format('%015.0f', math.floor(value * 10^(math.min(28,14-mag)))) end return sortkey; end function p.sortKeyForNumber(frame) local args = getArgs(frame); return p._sortKeyForNumber(args[1] or "") end return p 61c7b121abc7df4d9f0cab5456de8cb0de4ed1e2 70 69 2023-10-05T12:32:52Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Sortkey]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local p = {} function p._encode(sortkey) -- Protect against sortkey nesting. -- Example: {{sort|{{dts|2013|07|07}}|{{dts|1990|12|01}}}} if string.find(sortkey, "sortkey") or string.find(sortkey, "data-sort-value") then return ""; end return mw.text.encode(sortkey) end function p.encode(frame) local args = getArgs(frame); return p._encode(args[1] or "") end local function valid_number(num) -- Return true if num is a valid number. -- In Scribunto (different from some standard Lua), when expressed as a string, -- overflow or other problems are indicated with text like "inf" or "nan" -- which are regarded as invalid here (each contains "n"). if type(num) == 'number' and tostring(num):find('n', 1, true) == nil then return true end end function p._sortKeyForNumber(value) local sortkey if not valid_number(value) then if value < 0 then sortkey = '1000000000000000000' else sortkey = '9000000000000000000' end elseif value == 0 then sortkey = '5000000000000000000' else local mag = math.floor(math.log10(math.abs(value)) + 1e-14) local prefix if value > 0 then prefix = 7000 + mag else prefix = 2999 - mag value = value + 10^(mag+1) end sortkey = string.format('%d', prefix) .. string.format('%015.0f', math.floor(value * 10^(math.min(28,14-mag)))) end return sortkey; end function p.sortKeyForNumber(frame) local args = getArgs(frame); return p._sortKeyForNumber(args[1] or "") end return p 61c7b121abc7df4d9f0cab5456de8cb0de4ed1e2 แม่แบบ:Age 10 42 71 2023-10-05T12:33:48Z PeachFullzZ 2 สร้างหน้าด้วย "<includeonly>{{#invoke:age|age_generic|template=age_full_years}}</includeonly><noinclude>{{documentation}}</noinclude>" wikitext text/x-wiki <includeonly>{{#invoke:age|age_generic|template=age_full_years}}</includeonly><noinclude>{{documentation}}</noinclude> 408297d023a10a7476a5619baf18073f55c9a207 มอดูล:Age 828 43 72 2023-10-05T12:34:49Z PeachFullzZ 2 สร้างหน้าด้วย "-- Implement various "age of" and other date-related templates. local mtext = { -- Message and other text that should be localized. -- Also need to localize text in table names in function dateDifference. ['mt-bad-param1'] = 'Invalid parameter $1', ['mt-bad-param2'] = 'Parameter $1=$2 is invalid', ['mt-bad-show'] = 'Parameter show=$1 is not supported here', ['mt-cannot-add'] = 'Cannot add "$1"..." Scribunto text/plain -- Implement various "age of" and other date-related templates. local mtext = { -- Message and other text that should be localized. -- Also need to localize text in table names in function dateDifference. ['mt-bad-param1'] = 'Invalid parameter $1', ['mt-bad-param2'] = 'Parameter $1=$2 is invalid', ['mt-bad-show'] = 'Parameter show=$1 is not supported here', ['mt-cannot-add'] = 'Cannot add "$1"', ['mt-conflicting-show'] = 'Parameter show=$1 conflicts with round=$2', ['mt-date-wrong-order'] = 'The second date must be later in time than the first date', ['mt-dd-future'] = 'Death date (first date) must not be in the future', ['mt-dd-wrong-order'] = 'Death date (first date) must be later in time than the birth date (second date)', ['mt-invalid-bd-age'] = 'Invalid birth date for calculating age', ['mt-invalid-dates-age'] = 'Invalid dates for calculating age', ['mt-invalid-end'] = 'Invalid end date in second parameter', ['mt-invalid-start'] = 'Invalid start date in first parameter', ['mt-need-jdn'] = 'Need valid Julian date number', ['mt-need-valid-bd'] = 'Need valid birth date: year, month, day', ['mt-need-valid-bd2'] = 'Need valid birth date (second date): year, month, day', ['mt-need-valid-date'] = 'Need valid date', ['mt-need-valid-dd'] = 'Need valid death date (first date): year, month, day', ['mt-need-valid-ymd'] = 'Need valid year, month, day', ['mt-need-valid-ymd-current'] = 'Need valid year|month|day or "currentdate"', ['mt-need-valid-ymd2'] = 'Second date should be year, month, day', ['mt-template-bad-name'] = 'The specified template name is not valid', ['mt-template-x'] = 'The template invoking this must have "|template=x" where x is the wanted operation', ['txt-and'] = ' and ', ['txt-or'] = '&nbsp;or ', ['txt-category'] = 'Category:Age error', ['txt-comma-and'] = ', and ', ['txt-error'] = 'Error: ', ['txt-format-default'] = 'mf', -- 'df' (day first = dmy) or 'mf' (month first = mdy) ['txt-module-convertnumeric'] = 'Module:ConvertNumeric', ['txt-module-date'] = 'Module:Date', ['txt-sandbox'] = 'sandbox', ['txt-bda'] = '<span style="display:none"> (<span class="bday">$1</span>) </span>$2<span class="noprint ForceAgeToShow"> (age&nbsp;$3)</span>', ['txt-dda'] = '$2<span style="display:none">($1)</span> (aged&nbsp;$3)', ['txt-bda-disp'] = 'disp_raw', -- disp_raw → age is a number only; disp_age → age is a number and unit (normally years but months or days if very young) ['txt-dda-disp'] = 'disp_raw', ['txt-dmy'] = '%-d %B %-Y', ['txt-mdy'] = '%B %-d, %-Y', } local isWarning = { ['mt-bad-param1'] = true, } local translate, from_en, to_en, isZero if translate then -- Functions to translate from en to local language and reverse go here. -- See example at [[:bn:Module:বয়স]]. else from_en = function (text) return text end isZero = function (text) return tonumber(text) == 0 end end local _Date, _currentDate local function getExports(frame) -- Return objects exported from the date module or its sandbox. if not _Date then local sandbox = frame:getTitle():find(mtext['txt-sandbox'], 1, true) and ('/' .. mtext['txt-sandbox']) or '' local datemod = require(mtext['txt-module-date'] .. sandbox) local realDate = datemod._Date _currentDate = datemod._current if to_en then _Date = function (...) local args = {} for i, v in ipairs({...}) do args[i] = to_en(v) end return realDate(unpack(args)) end else _Date = realDate end end return _Date, _currentDate end local Collection -- a table to hold items Collection = { add = function (self, item) if item ~= nil then self.n = self.n + 1 self[self.n] = item end end, join = function (self, sep) return table.concat(self, sep) end, remove = function (self, pos) if self.n > 0 and (pos == nil or (0 < pos and pos <= self.n)) then self.n = self.n - 1 return table.remove(self, pos) end end, sort = function (self, comp) table.sort(self, comp) end, new = function () return setmetatable({n = 0}, Collection) end } Collection.__index = Collection local function stripToNil(text) -- If text is a string, return its trimmed content, or nil if empty. -- Otherwise return text (which may, for example, be nil). if type(text) == 'string' then text = text:match('(%S.-)%s*$') end return text end local function dateFormat(args) -- Return string for wanted date format. local default = mtext['txt-format-default'] local other = default == 'df' and 'mf' or 'df' local wanted = stripToNil(args[other]) and other or default return wanted == 'df' and mtext['txt-dmy'] or mtext['txt-mdy'] end local function substituteParameters(text, ...) -- Return text after substituting any given parameters for $1, $2, etc. return mw.message.newRawMessage(text, ...):plain() end local function yes(parameter) -- Return true if parameter should be interpreted as "yes". -- Do not want to accept mixed upper/lowercase unless done by current templates. -- Need to accept "on" because "round=on" is wanted. return ({ y = true, yes = true, on = true })[parameter] end local function message(msg, ...) -- Return formatted message text for an error or warning. local function getText(msg) return mtext[msg] or error('Bug: message "' .. tostring(msg) .. '" not defined') end local categories = { error = mtext['txt-category'], warning = mtext['txt-category'], } local a, b, k, category local text = substituteParameters(getText(msg), ...) if isWarning[msg] then a = '<sup>[<i>' b = '</i>]</sup>' k = 'warning' else a = '<strong class="error">' .. getText('txt-error') b = '</strong>' k = 'error' end if mw.title.getCurrentTitle():inNamespaces(0) then -- Category only in namespaces: 0=article. category = '[[' .. categories[k] .. ']]' end return a .. mw.text.nowiki(text) .. b .. (category or '') end local function formatNumber(number) -- Return the given number formatted with commas as group separators, -- given that the number is an integer. local numstr = tostring(number) local length = #numstr local places = Collection.new() local pos = 0 repeat places:add(pos) pos = pos + 3 until pos >= length places:add(length) local groups = Collection.new() for i = places.n, 2, -1 do local p1 = length - places[i] + 1 local p2 = length - places[i - 1] groups:add(numstr:sub(p1, p2)) end return groups:join(',') end local function spellNumber(number, options, i) -- Return result of spelling number, or -- return number (as a string) if cannot spell it. -- i == 1 for the first number which can optionally start with an uppercase letter. number = tostring(number) return require(mtext['txt-module-convertnumeric']).spell_number( number, nil, -- fraction numerator nil, -- fraction denominator i == 1 and options.upper, -- true: 'One' instead of 'one' not options.us, -- true: use 'and' between tens/ones etc options.adj, -- true: hyphenated options.ordinal -- true: 'first' instead of 'one' ) or number end local function makeExtra(args, flagCurrent) -- Return extra text that will be inserted before the visible result -- but after any sort key. local extra = args.prefix or '' if mw.ustring.len(extra) > 1 then -- Parameter "~" gives "~3" whereas "over" gives "over 3". if extra:sub(-6, -1) ~= '&nbsp;' then extra = extra .. ' ' end end if flagCurrent then extra = '<span class="currentage"></span>' .. extra end return extra end local function makeSort(value, sortable) -- Return a sort key if requested. -- Assume value is a valid number which has not overflowed. if sortable == 'sortable_table' or sortable == 'sortable_on' or sortable == 'sortable_debug' then local sortKey if value == 0 then sortKey = '5000000000000000000' else local mag = math.floor(math.log10(math.abs(value)) + 1e-14) if value > 0 then sortKey = 7000 + mag else sortKey = 2999 - mag value = value + 10^(mag+1) end sortKey = string.format('%d', sortKey) .. string.format('%015.0f', math.floor(value * 10^(14-mag))) end local result if sortable == 'sortable_table' then result = 'data-sort-value="_SORTKEY_"|' elseif sortable == 'sortable_debug' then result = '<span data-sort-value="_SORTKEY_♠"><span style="border:1px solid">_SORTKEY_♠</span></span>' else result = '<span data-sort-value="_SORTKEY_♠"></span>' end return (result:gsub('_SORTKEY_', sortKey)) end end local translateParameters = { abbr = { off = 'abbr_off', on = 'abbr_on', }, disp = { age = 'disp_age', raw = 'disp_raw', }, format = { raw = 'format_raw', commas = 'format_commas', }, round = { on = 'on', yes = 'on', months = 'ym', weeks = 'ymw', days = 'ymd', hours = 'ymdh', }, sep = { comma = 'sep_comma', [','] = 'sep_comma', serialcomma = 'sep_serialcomma', space = 'sep_space', }, show = { hide = { id = 'hide' }, y = { 'y', id = 'y' }, ym = { 'y', 'm', id = 'ym' }, ymd = { 'y', 'm', 'd', id = 'ymd' }, ymw = { 'y', 'm', 'w', id = 'ymw' }, ymwd = { 'y', 'm', 'w', 'd', id = 'ymwd' }, yd = { 'y', 'd', id = 'yd', keepZero = true }, m = { 'm', id = 'm' }, md = { 'm', 'd', id = 'md' }, w = { 'w', id = 'w' }, wd = { 'w', 'd', id = 'wd' }, h = { 'H', id = 'h' }, hm = { 'H', 'M', id = 'hm' }, hms = { 'H', 'M', 'S', id = 'hms' }, M = { 'M', id = 'M' }, s = { 'S', id = 's' }, d = { 'd', id = 'd' }, dh = { 'd', 'H', id = 'dh' }, dhm = { 'd', 'H', 'M', id = 'dhm' }, dhms = { 'd', 'H', 'M', 'S', id = 'dhms' }, ymdh = { 'y', 'm', 'd', 'H', id = 'ymdh' }, ymdhm = { 'y', 'm', 'd', 'H', 'M', id = 'ymdhm' }, ymwdh = { 'y', 'm', 'w', 'd', 'H', id = 'ymwdh' }, ymwdhm = { 'y', 'm', 'w', 'd', 'H', 'M', id = 'ymwdhm' }, }, sortable = { off = false, on = 'sortable_on', table = 'sortable_table', debug = 'sortable_debug', }, } local spellOptions = { cardinal = {}, Cardinal = { upper = true }, cardinal_us = { us = true }, Cardinal_us = { us = true, upper = true }, ordinal = { ordinal = true }, Ordinal = { ordinal = true, upper = true }, ordinal_us = { ordinal = true, us = true }, Ordinal_us = { ordinal = true, us = true, upper = true }, } local function dateExtract(frame) -- Return part of a date after performing an optional operation. local Date = getExports(frame) local args = frame:getParent().args local parms = {} for i, v in ipairs(args) do parms[i] = v end if yes(args.fix) then table.insert(parms, 'fix') end if yes(args.partial) then table.insert(parms, 'partial') end local show = stripToNil(args.show) or 'dmy' local date = Date(unpack(parms)) if not date then if show == 'format' then return 'error' end return message('mt-need-valid-date') end local add = stripToNil(args.add) if add then for item in add:gmatch('%S+') do date = date + item if not date then return message('mt-cannot-add', item) end end end local sortKey, result local sortable = translateParameters.sortable[args.sortable] if sortable then local value = (date.partial and date.partial.first or date).jdz sortKey = makeSort(value, sortable) end if show ~= 'hide' then result = date[show] if result == nil then result = from_en(date:text(show)) elseif type(result) == 'boolean' then result = result and '1' or '0' else result = from_en(tostring(result)) end end return (sortKey or '') .. makeExtra(args) .. (result or '') end local function rangeJoin(range) -- Return text to be used between a range of ages. return range == 'dash' and '–' or mtext['txt-or'] end local function makeText(values, components, names, options, noUpper) -- Return wikitext representing an age or duration. local text = Collection.new() local count = #values local sep = names.sep or '' for i, v in ipairs(values) do -- v is a number (say 4 for 4 years), or a table ({4,5} for 4 or 5 years). local islist = type(v) == 'table' if (islist or v > 0) or (text.n == 0 and i == count) or (text.n > 0 and components.keepZero) then local fmt, vstr if options.spell then fmt = function(number) return spellNumber(number, options.spell, noUpper or i) end elseif i == 1 and options.format == 'format_commas' then -- Numbers after the first should be small and not need formatting. fmt = formatNumber else fmt = tostring end if islist then vstr = fmt(v[1]) .. rangeJoin(options.range) noUpper = true vstr = vstr .. fmt(v[2]) else vstr = fmt(v) end local name = names[components[i]] if name then if type(name) == 'table' then name = mw.getContentLanguage():plural(islist and v[2] or v, name) end text:add(vstr .. sep .. name) else text:add(vstr) end end end local first, last if options.join == 'sep_space' then first = ' ' last = ' ' elseif options.join == 'sep_comma' then first = ', ' last = ', ' elseif options.join == 'sep_serialcomma' and text.n > 2 then first = ', ' last = mtext['txt-comma-and'] else first = ', ' last = mtext['txt-and'] end for i, v in ipairs(text) do if i < text.n then text[i] = v .. (i + 1 < text.n and first or last) end end local sign = '' if options.isnegative then -- Do not display negative zero. if text.n > 1 or (text.n == 1 and text[1]:sub(1, 1) ~= '0' ) then if options.format == 'format_raw' then sign = '-' -- plain hyphen so result can be used in a calculation else sign = '−' -- Unicode U+2212 MINUS SIGN end end end return (options.sortKey or '') .. (options.extra or '') .. sign .. text:join() .. (options.suffix or '') end local function dateDifference(parms) -- Return a formatted date difference using the given parameters -- which have been validated. local names = { -- Each name is: -- * a string if no plural form of the name is used; or -- * a table of strings, one of which is selected using the rules at -- https://translatewiki.net/wiki/Plural/Mediawiki_plural_rules abbr_off = { sep = '&nbsp;', y = {'year', 'years'}, m = {'month', 'months'}, w = {'week', 'weeks'}, d = {'day', 'days'}, H = {'hour', 'hours'}, M = {'minute', 'minutes'}, S = {'second', 'seconds'}, }, abbr_on = { y = 'y', m = 'm', w = 'w', d = 'd', H = 'h', M = 'm', S = 's', }, abbr_infant = { -- for {{age for infant}} sep = '&nbsp;', y = {'yr', 'yrs'}, m = {'mo', 'mos'}, w = {'wk', 'wks'}, d = {'day', 'days'}, H = {'hr', 'hrs'}, M = {'min', 'mins'}, S = {'sec', 'secs'}, }, abbr_raw = {}, } local diff = parms.diff -- must be a valid date difference local show = parms.show -- may be nil; default is set below local abbr = parms.abbr or 'abbr_off' local defaultJoin if abbr ~= 'abbr_off' then defaultJoin = 'sep_space' end if not show then show = 'ymd' if parms.disp == 'disp_age' then if diff.years < 3 then defaultJoin = 'sep_space' if diff.years >= 1 then show = 'ym' else show = 'md' end else show = 'y' end end end if type(show) ~= 'table' then show = translateParameters.show[show] end if parms.disp == 'disp_raw' then defaultJoin = 'sep_space' abbr = 'abbr_raw' elseif parms.wantSc then defaultJoin = 'sep_serialcomma' end local diffOptions = { round = parms.round, duration = parms.wantDuration, range = parms.range and true or nil, } local sortKey if parms.sortable then local value = diff.age_days + (parms.wantDuration and 1 or 0) -- days and fraction of a day if diff.isnegative then value = -value end sortKey = makeSort(value, parms.sortable) end local textOptions = { extra = parms.extra, format = parms.format, join = parms.sep or defaultJoin, isnegative = diff.isnegative, range = parms.range, sortKey = sortKey, spell = parms.spell, suffix = parms.suffix, -- not currently used } if show.id == 'hide' then return sortKey or '' end local values = { diff:age(show.id, diffOptions) } if values[1] then return makeText(values, show, names[abbr], textOptions) end if diff.partial then -- Handle a more complex range such as -- {{age_yd|20 Dec 2001|2003|range=yes}} → 1 year, 12 days or 2 years, 11 days local opt = { format = textOptions.format, join = textOptions.join, isnegative = textOptions.isnegative, spell = textOptions.spell, } return (textOptions.sortKey or '') .. makeText({ diff.partial.mindiff:age(show.id, diffOptions) }, show, names[abbr], opt) .. rangeJoin(textOptions.range) .. makeText({ diff.partial.maxdiff:age(show.id, diffOptions) }, show, names[abbr], opt, true) .. (textOptions.suffix or '') end return message('mt-bad-show', show.id) end local function getDates(frame, getopt) -- Parse template parameters and return one of: -- * date (a date table, if single) -- * date1, date2 (two date tables, if not single) -- * text (a string error message) -- A missing date is optionally replaced with the current date. -- If wantMixture is true, a missing date component is replaced -- from the current date, so can get a bizarre mixture of -- specified/current y/m/d as has been done by some "age" templates. -- Some results may be placed in table getopt. local Date, currentDate = getExports(frame) getopt = getopt or {} local function flagCurrent(text) -- This allows the calling template to detect if the current date has been used, -- that is, whether both dates have been entered in a template expecting two. -- For example, an infobox may want the age when an event occurred, not the current age. -- Don't bother detecting if wantMixture is used because not needed and it is a poor option. if not text then if getopt.noMissing then return nil -- this gives a nil date which gives an error end text = 'currentdate' if getopt.flag == 'usesCurrent' then getopt.usesCurrent = true end end return text end local args = frame:getParent().args local fields = {} local isNamed = args.year or args.year1 or args.year2 or args.month or args.month1 or args.month2 or args.day or args.day1 or args.day2 if isNamed then fields[1] = args.year1 or args.year fields[2] = args.month1 or args.month fields[3] = args.day1 or args.day fields[4] = args.year2 fields[5] = args.month2 fields[6] = args.day2 else for i = 1, 6 do fields[i] = args[i] end end local imax = 0 for i = 1, 6 do fields[i] = stripToNil(fields[i]) if fields[i] then imax = i end if getopt.omitZero and i % 3 ~= 1 then -- omit zero months and days as unknown values but keep year 0 which is 1 BCE if isZero(fields[i]) then fields[i] = nil getopt.partial = true end end end local fix = getopt.fix and 'fix' or '' local partialText = getopt.partial and 'partial' or '' local dates = {} if isNamed or imax >= 3 then local nrDates = getopt.single and 1 or 2 if getopt.wantMixture then -- Cannot be partial since empty fields are set from current. local components = { 'year', 'month', 'day' } for i = 1, nrDates * 3 do fields[i] = fields[i] or currentDate[components[i > 3 and i - 3 or i]] end for i = 1, nrDates do local index = i == 1 and 1 or 4 local y, m, d = fields[index], fields[index+1], fields[index+2] if (m == 2 or m == '2') and (d == 29 or d == '29') then -- Workaround error with following which attempt to use invalid date 2001-02-29. -- {{age_ymwd|year1=2001|year2=2004|month2=2|day2=29}} -- {{age_ymwd|year1=2001|month1=2|year2=2004|month2=1|day2=29}} -- TODO Get rid of wantMixture because even this ugly code does not handle -- 'Feb' or 'February' or 'feb' or 'february'. if not ((y % 4 == 0 and y % 100 ~= 0) or y % 400 == 0) then d = 28 end end dates[i] = Date(y, m, d) end else -- If partial dates are allowed, accept -- year only, or -- year and month only -- Do not accept year and day without a month because that makes no sense -- (and because, for example, Date('partial', 2001, nil, 12) sets day = nil, not 12). for i = 1, nrDates do local index = i == 1 and 1 or 4 local y, m, d = fields[index], fields[index+1], fields[index+2] if (getopt.partial and y and (m or not d)) or (y and m and d) then dates[i] = Date(fix, partialText, y, m, d) elseif not y and not m and not d then dates[i] = Date(flagCurrent()) end end end else getopt.textdates = true -- have parsed each date from a single text field dates[1] = Date(fix, partialText, flagCurrent(fields[1])) if not getopt.single then dates[2] = Date(fix, partialText, flagCurrent(fields[2])) end end if not dates[1] then return message(getopt.missing1 or 'mt-need-valid-ymd') end if getopt.single then return dates[1] end if not dates[2] then return message(getopt.missing2 or 'mt-need-valid-ymd2') end return dates[1], dates[2] end local function ageGeneric(frame) -- Return the result required by the specified template. -- Can use sortable=x where x = on/table/off/debug in any supported template. -- Some templates default to sortable=on but can be overridden. local name = frame.args.template if not name then return message('mt-template-x') end local args = frame:getParent().args local specs = { age_days = { -- {{age in days}} show = 'd', disp = 'disp_raw', }, age_days_nts = { -- {{age in days nts}} show = 'd', disp = 'disp_raw', format = 'format_commas', sortable = 'on', }, duration_days = { -- {{duration in days}} show = 'd', disp = 'disp_raw', duration = true, }, duration_days_nts = { -- {{duration in days nts}} show = 'd', disp = 'disp_raw', format = 'format_commas', sortable = 'on', duration = true, }, age_full_years = { -- {{age}} show = 'y', abbr = 'abbr_raw', flag = 'usesCurrent', omitZero = true, range = 'dash', }, age_full_years_nts = { -- {{age nts}} show = 'y', abbr = 'abbr_raw', format = 'format_commas', sortable = 'on', }, age_in_years = { -- {{age in years}} show = 'y', abbr = 'abbr_raw', negative = 'error', range = 'dash', }, age_in_years_nts = { -- {{age in years nts}} show = 'y', abbr = 'abbr_raw', negative = 'error', range = 'dash', format = 'format_commas', sortable = 'on', }, age_infant = { -- {{age for infant}} -- Do not set show because special processing is done later. abbr = yes(args.abbr) and 'abbr_infant' or 'abbr_off', disp = 'disp_age', sep = 'sep_space', sortable = 'on', }, age_m = { -- {{age in months}} show = 'm', disp = 'disp_raw', }, age_w = { -- {{age in weeks}} show = 'w', disp = 'disp_raw', }, age_wd = { -- {{age in weeks and days}} show = 'wd', }, age_yd = { -- {{age in years and days}} show = 'yd', format = 'format_commas', sep = args.sep ~= 'and' and 'sep_comma' or nil, }, age_yd_nts = { -- {{age in years and days nts}} show = 'yd', format = 'format_commas', sep = args.sep ~= 'and' and 'sep_comma' or nil, sortable = 'on', }, age_ym = { -- {{age in years and months}} show = 'ym', sep = 'sep_comma', }, age_ymd = { -- {{age in years, months and days}} show = 'ymd', range = true, }, age_ymwd = { -- {{age in years, months, weeks and days}} show = 'ymwd', wantMixture = true, }, } local spec = specs[name] if not spec then return message('mt-template-bad-name') end if name == 'age_days' then local su = stripToNil(args['show unit']) if su then if su == 'abbr' or su == 'full' then spec.disp = nil spec.abbr = su == 'abbr' and 'abbr_on' or nil end end end local partial, autofill local range = stripToNil(args.range) or spec.range if range then -- Suppose partial dates are used and age could be 11 or 12 years. -- "|range=" (empty value) has no effect (spec is used). -- "|range=yes" or spec.range == true sets range = true (gives "11 or 12") -- "|range=dash" or spec.range == 'dash' sets range = 'dash' (gives "11–12"). -- "|range=no" or spec.range == 'no' sets range = nil and fills each date in the diff (gives "12"). -- ("on" is equivalent to "yes", and "off" is equivalent to "no"). -- "|range=OTHER" sets range = nil and rejects partial dates. range = ({ dash = 'dash', off = 'no', no = 'no', [true] = true })[range] or yes(range) if range then partial = true -- accept partial dates with a possible age range for the result if range == 'no' then autofill = true -- missing month/day in first or second date are filled from other date or 1 range = nil end end end local getopt = { fix = yes(args.fix), flag = stripToNil(args.flag) or spec.flag, omitZero = spec.omitZero, partial = partial, wantMixture = spec.wantMixture, } local date1, date2 = getDates(frame, getopt) if type(date1) == 'string' then return date1 end local format = stripToNil(args.format) local spell = spellOptions[format] if format then format = 'format_' .. format elseif name == 'age_days' and getopt.textdates then format = 'format_commas' end local parms = { diff = date2:subtract(date1, { fill = autofill }), wantDuration = spec.duration or yes(args.duration), range = range, wantSc = yes(args.sc), show = args.show == 'hide' and 'hide' or spec.show, abbr = spec.abbr, disp = spec.disp, extra = makeExtra(args, getopt.usesCurrent and format ~= 'format_raw'), format = format or spec.format, round = yes(args.round), sep = spec.sep, sortable = translateParameters.sortable[args.sortable or spec.sortable], spell = spell, } if (spec.negative or frame.args.negative) == 'error' and parms.diff.isnegative then return message('mt-date-wrong-order') end return from_en(dateDifference(parms)) end local function bda(frame) -- Implement [[Template:Birth date and age]]. local args = frame:getParent().args local options = { missing1 = 'mt-need-valid-bd', noMissing = true, single = true, } local date = getDates(frame, options) if type(date) == 'string' then return date -- error text end local Date = getExports(frame) local diff = Date('currentdate') - date if diff.isnegative or diff.years > 150 then return message('mt-invalid-bd-age') end local disp = mtext['txt-bda-disp'] local show = 'y' if diff.years < 2 then disp = 'disp_age' if diff.years == 0 and diff.months == 0 then show = 'd' else show = 'm' end end local result = substituteParameters( mtext['txt-bda'], date:text('%-Y-%m-%d'), from_en(date:text(dateFormat(args))), from_en(dateDifference({ diff = diff, show = show, abbr = 'abbr_off', disp = disp, sep = 'sep_space', })) ) local warnings = tonumber(frame.args.warnings) if warnings and warnings > 0 then local good = { df = true, mf = true, day = true, day1 = true, month = true, month1 = true, year = true, year1 = true, } local invalid local imax = options.textdates and 1 or 3 for k, _ in pairs(args) do if type(k) == 'number' then if k > imax then invalid = tostring(k) break end else if not good[k] then invalid = k break end end end if invalid then result = result .. message('mt-bad-param1', invalid) end end return result end local function dda(frame) -- Implement [[Template:Death date and age]]. local args = frame:getParent().args local options = { missing1 = 'mt-need-valid-dd', missing2 = 'mt-need-valid-bd2', noMissing = true, partial = true, } local date1, date2 = getDates(frame, options) if type(date1) == 'string' then return date1 end local diff = date1 - date2 if diff.isnegative then return message('mt-dd-wrong-order') end local Date = getExports(frame) local today = Date('currentdate') + 1 -- one day in future allows for timezones if date1 > today then return message('mt-dd-future') end local years if diff.partial then years = diff.partial.years years = type(years) == 'table' and years[2] or years else years = diff.years end if years > 150 then return message('mt-invalid-dates-age') end local fmt_date, fmt_ymd if date1.day then -- y, m, d known fmt_date = dateFormat(args) fmt_ymd = '%-Y-%m-%d' elseif date1.month then -- y, m known; d unknown fmt_date = '%B %-Y' fmt_ymd = '%-Y-%m-00' else -- y known; m, d unknown fmt_date = '%-Y' fmt_ymd = '%-Y-00-00' end local sortKey local sortable = translateParameters.sortable[args.sortable] if sortable then local value = (date1.partial and date1.partial.first or date1).jdz sortKey = makeSort(value, sortable) end local result = (sortKey or '') .. substituteParameters( mtext['txt-dda'], date1:text(fmt_ymd), from_en(date1:text(fmt_date)), from_en(dateDifference({ diff = diff, show = 'y', abbr = 'abbr_off', disp = mtext['txt-dda-disp'], range = 'dash', sep = 'sep_space', })) ) local warnings = tonumber(frame.args.warnings) if warnings and warnings > 0 then local good = { df = true, mf = true, } local invalid local imax = options.textdates and 2 or 6 for k, _ in pairs(args) do if type(k) == 'number' then if k > imax then invalid = tostring(k) break end else if not good[k] then invalid = k break end end end if invalid then result = result .. message('mt-bad-param1', invalid) end end return result end local function dateToGsd(frame) -- Implement [[Template:Gregorian serial date]]. -- Return Gregorian serial date of the given date, or the current date. -- The returned value is negative for dates before 1 January 1 AD -- despite the fact that GSD is not defined for such dates. local date = getDates(frame, { wantMixture=true, single=true }) if type(date) == 'string' then return date end return tostring(date.gsd) end local function jdToDate(frame) -- Return formatted date from a Julian date. -- The result includes a time if the input includes a fraction. -- The word 'Julian' is accepted for the Julian calendar. local Date = getExports(frame) local args = frame:getParent().args local date = Date('juliandate', args[1], args[2]) if date then return from_en(date:text()) end return message('mt-need-jdn') end local function dateToJd(frame) -- Return Julian date (a number) from a date which may include a time, -- or the current date ('currentdate') or current date and time ('currentdatetime'). -- The word 'Julian' is accepted for the Julian calendar. local Date = getExports(frame) local args = frame:getParent().args local date = Date(args[1], args[2], args[3], args[4], args[5], args[6], args[7]) if date then return tostring(date.jd) end return message('mt-need-valid-ymd-current') end local function timeInterval(frame) -- Implement [[Template:Time interval]]. -- There are two positional arguments: date1, date2. -- The default for each is the current date and time. -- Result is date2 - date1 formatted. local Date = getExports(frame) local args = frame:getParent().args local parms = { extra = makeExtra(args), wantDuration = yes(args.duration), range = yes(args.range) or (args.range == 'dash' and 'dash' or nil), wantSc = yes(args.sc), } local fix = yes(args.fix) and 'fix' or '' local date1 = Date(fix, 'partial', stripToNil(args[1]) or 'currentdatetime') if not date1 then return message('mt-invalid-start') end local date2 = Date(fix, 'partial', stripToNil(args[2]) or 'currentdatetime') if not date2 then return message('mt-invalid-end') end parms.diff = date2 - date1 for argname, translate in pairs(translateParameters) do local parm = stripToNil(args[argname]) if parm then parm = translate[parm] if parm == nil then -- test for nil because false is a valid setting return message('mt-bad-param2', argname, args[argname]) end parms[argname] = parm end end if parms.round then local round = parms.round local show = parms.show if round ~= 'on' then if show then if show.id ~= round then return message('mt-conflicting-show', args.show, args.round) end else parms.show = translateParameters.show[round] end end parms.round = true end return from_en(dateDifference(parms)) end return { age_generic = ageGeneric, -- can emulate several age templates birth_date_and_age = bda, -- Template:Birth_date_and_age death_date_and_age = dda, -- Template:Death_date_and_age gsd = dateToGsd, -- Template:Gregorian_serial_date extract = dateExtract, -- Template:Extract jd_to_date = jdToDate, -- Template:? JULIANDAY = dateToJd, -- Template:JULIANDAY time_interval = timeInterval, -- Template:Time_interval } 094ef43a81ac2366c838b6ad889ed0ffe5a1eec4 73 72 2023-10-05T12:35:07Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Age]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- Implement various "age of" and other date-related templates. local mtext = { -- Message and other text that should be localized. -- Also need to localize text in table names in function dateDifference. ['mt-bad-param1'] = 'Invalid parameter $1', ['mt-bad-param2'] = 'Parameter $1=$2 is invalid', ['mt-bad-show'] = 'Parameter show=$1 is not supported here', ['mt-cannot-add'] = 'Cannot add "$1"', ['mt-conflicting-show'] = 'Parameter show=$1 conflicts with round=$2', ['mt-date-wrong-order'] = 'The second date must be later in time than the first date', ['mt-dd-future'] = 'Death date (first date) must not be in the future', ['mt-dd-wrong-order'] = 'Death date (first date) must be later in time than the birth date (second date)', ['mt-invalid-bd-age'] = 'Invalid birth date for calculating age', ['mt-invalid-dates-age'] = 'Invalid dates for calculating age', ['mt-invalid-end'] = 'Invalid end date in second parameter', ['mt-invalid-start'] = 'Invalid start date in first parameter', ['mt-need-jdn'] = 'Need valid Julian date number', ['mt-need-valid-bd'] = 'Need valid birth date: year, month, day', ['mt-need-valid-bd2'] = 'Need valid birth date (second date): year, month, day', ['mt-need-valid-date'] = 'Need valid date', ['mt-need-valid-dd'] = 'Need valid death date (first date): year, month, day', ['mt-need-valid-ymd'] = 'Need valid year, month, day', ['mt-need-valid-ymd-current'] = 'Need valid year|month|day or "currentdate"', ['mt-need-valid-ymd2'] = 'Second date should be year, month, day', ['mt-template-bad-name'] = 'The specified template name is not valid', ['mt-template-x'] = 'The template invoking this must have "|template=x" where x is the wanted operation', ['txt-and'] = ' and ', ['txt-or'] = '&nbsp;or ', ['txt-category'] = 'Category:Age error', ['txt-comma-and'] = ', and ', ['txt-error'] = 'Error: ', ['txt-format-default'] = 'mf', -- 'df' (day first = dmy) or 'mf' (month first = mdy) ['txt-module-convertnumeric'] = 'Module:ConvertNumeric', ['txt-module-date'] = 'Module:Date', ['txt-sandbox'] = 'sandbox', ['txt-bda'] = '<span style="display:none"> (<span class="bday">$1</span>) </span>$2<span class="noprint ForceAgeToShow"> (age&nbsp;$3)</span>', ['txt-dda'] = '$2<span style="display:none">($1)</span> (aged&nbsp;$3)', ['txt-bda-disp'] = 'disp_raw', -- disp_raw → age is a number only; disp_age → age is a number and unit (normally years but months or days if very young) ['txt-dda-disp'] = 'disp_raw', ['txt-dmy'] = '%-d %B %-Y', ['txt-mdy'] = '%B %-d, %-Y', } local isWarning = { ['mt-bad-param1'] = true, } local translate, from_en, to_en, isZero if translate then -- Functions to translate from en to local language and reverse go here. -- See example at [[:bn:Module:বয়স]]. else from_en = function (text) return text end isZero = function (text) return tonumber(text) == 0 end end local _Date, _currentDate local function getExports(frame) -- Return objects exported from the date module or its sandbox. if not _Date then local sandbox = frame:getTitle():find(mtext['txt-sandbox'], 1, true) and ('/' .. mtext['txt-sandbox']) or '' local datemod = require(mtext['txt-module-date'] .. sandbox) local realDate = datemod._Date _currentDate = datemod._current if to_en then _Date = function (...) local args = {} for i, v in ipairs({...}) do args[i] = to_en(v) end return realDate(unpack(args)) end else _Date = realDate end end return _Date, _currentDate end local Collection -- a table to hold items Collection = { add = function (self, item) if item ~= nil then self.n = self.n + 1 self[self.n] = item end end, join = function (self, sep) return table.concat(self, sep) end, remove = function (self, pos) if self.n > 0 and (pos == nil or (0 < pos and pos <= self.n)) then self.n = self.n - 1 return table.remove(self, pos) end end, sort = function (self, comp) table.sort(self, comp) end, new = function () return setmetatable({n = 0}, Collection) end } Collection.__index = Collection local function stripToNil(text) -- If text is a string, return its trimmed content, or nil if empty. -- Otherwise return text (which may, for example, be nil). if type(text) == 'string' then text = text:match('(%S.-)%s*$') end return text end local function dateFormat(args) -- Return string for wanted date format. local default = mtext['txt-format-default'] local other = default == 'df' and 'mf' or 'df' local wanted = stripToNil(args[other]) and other or default return wanted == 'df' and mtext['txt-dmy'] or mtext['txt-mdy'] end local function substituteParameters(text, ...) -- Return text after substituting any given parameters for $1, $2, etc. return mw.message.newRawMessage(text, ...):plain() end local function yes(parameter) -- Return true if parameter should be interpreted as "yes". -- Do not want to accept mixed upper/lowercase unless done by current templates. -- Need to accept "on" because "round=on" is wanted. return ({ y = true, yes = true, on = true })[parameter] end local function message(msg, ...) -- Return formatted message text for an error or warning. local function getText(msg) return mtext[msg] or error('Bug: message "' .. tostring(msg) .. '" not defined') end local categories = { error = mtext['txt-category'], warning = mtext['txt-category'], } local a, b, k, category local text = substituteParameters(getText(msg), ...) if isWarning[msg] then a = '<sup>[<i>' b = '</i>]</sup>' k = 'warning' else a = '<strong class="error">' .. getText('txt-error') b = '</strong>' k = 'error' end if mw.title.getCurrentTitle():inNamespaces(0) then -- Category only in namespaces: 0=article. category = '[[' .. categories[k] .. ']]' end return a .. mw.text.nowiki(text) .. b .. (category or '') end local function formatNumber(number) -- Return the given number formatted with commas as group separators, -- given that the number is an integer. local numstr = tostring(number) local length = #numstr local places = Collection.new() local pos = 0 repeat places:add(pos) pos = pos + 3 until pos >= length places:add(length) local groups = Collection.new() for i = places.n, 2, -1 do local p1 = length - places[i] + 1 local p2 = length - places[i - 1] groups:add(numstr:sub(p1, p2)) end return groups:join(',') end local function spellNumber(number, options, i) -- Return result of spelling number, or -- return number (as a string) if cannot spell it. -- i == 1 for the first number which can optionally start with an uppercase letter. number = tostring(number) return require(mtext['txt-module-convertnumeric']).spell_number( number, nil, -- fraction numerator nil, -- fraction denominator i == 1 and options.upper, -- true: 'One' instead of 'one' not options.us, -- true: use 'and' between tens/ones etc options.adj, -- true: hyphenated options.ordinal -- true: 'first' instead of 'one' ) or number end local function makeExtra(args, flagCurrent) -- Return extra text that will be inserted before the visible result -- but after any sort key. local extra = args.prefix or '' if mw.ustring.len(extra) > 1 then -- Parameter "~" gives "~3" whereas "over" gives "over 3". if extra:sub(-6, -1) ~= '&nbsp;' then extra = extra .. ' ' end end if flagCurrent then extra = '<span class="currentage"></span>' .. extra end return extra end local function makeSort(value, sortable) -- Return a sort key if requested. -- Assume value is a valid number which has not overflowed. if sortable == 'sortable_table' or sortable == 'sortable_on' or sortable == 'sortable_debug' then local sortKey if value == 0 then sortKey = '5000000000000000000' else local mag = math.floor(math.log10(math.abs(value)) + 1e-14) if value > 0 then sortKey = 7000 + mag else sortKey = 2999 - mag value = value + 10^(mag+1) end sortKey = string.format('%d', sortKey) .. string.format('%015.0f', math.floor(value * 10^(14-mag))) end local result if sortable == 'sortable_table' then result = 'data-sort-value="_SORTKEY_"|' elseif sortable == 'sortable_debug' then result = '<span data-sort-value="_SORTKEY_♠"><span style="border:1px solid">_SORTKEY_♠</span></span>' else result = '<span data-sort-value="_SORTKEY_♠"></span>' end return (result:gsub('_SORTKEY_', sortKey)) end end local translateParameters = { abbr = { off = 'abbr_off', on = 'abbr_on', }, disp = { age = 'disp_age', raw = 'disp_raw', }, format = { raw = 'format_raw', commas = 'format_commas', }, round = { on = 'on', yes = 'on', months = 'ym', weeks = 'ymw', days = 'ymd', hours = 'ymdh', }, sep = { comma = 'sep_comma', [','] = 'sep_comma', serialcomma = 'sep_serialcomma', space = 'sep_space', }, show = { hide = { id = 'hide' }, y = { 'y', id = 'y' }, ym = { 'y', 'm', id = 'ym' }, ymd = { 'y', 'm', 'd', id = 'ymd' }, ymw = { 'y', 'm', 'w', id = 'ymw' }, ymwd = { 'y', 'm', 'w', 'd', id = 'ymwd' }, yd = { 'y', 'd', id = 'yd', keepZero = true }, m = { 'm', id = 'm' }, md = { 'm', 'd', id = 'md' }, w = { 'w', id = 'w' }, wd = { 'w', 'd', id = 'wd' }, h = { 'H', id = 'h' }, hm = { 'H', 'M', id = 'hm' }, hms = { 'H', 'M', 'S', id = 'hms' }, M = { 'M', id = 'M' }, s = { 'S', id = 's' }, d = { 'd', id = 'd' }, dh = { 'd', 'H', id = 'dh' }, dhm = { 'd', 'H', 'M', id = 'dhm' }, dhms = { 'd', 'H', 'M', 'S', id = 'dhms' }, ymdh = { 'y', 'm', 'd', 'H', id = 'ymdh' }, ymdhm = { 'y', 'm', 'd', 'H', 'M', id = 'ymdhm' }, ymwdh = { 'y', 'm', 'w', 'd', 'H', id = 'ymwdh' }, ymwdhm = { 'y', 'm', 'w', 'd', 'H', 'M', id = 'ymwdhm' }, }, sortable = { off = false, on = 'sortable_on', table = 'sortable_table', debug = 'sortable_debug', }, } local spellOptions = { cardinal = {}, Cardinal = { upper = true }, cardinal_us = { us = true }, Cardinal_us = { us = true, upper = true }, ordinal = { ordinal = true }, Ordinal = { ordinal = true, upper = true }, ordinal_us = { ordinal = true, us = true }, Ordinal_us = { ordinal = true, us = true, upper = true }, } local function dateExtract(frame) -- Return part of a date after performing an optional operation. local Date = getExports(frame) local args = frame:getParent().args local parms = {} for i, v in ipairs(args) do parms[i] = v end if yes(args.fix) then table.insert(parms, 'fix') end if yes(args.partial) then table.insert(parms, 'partial') end local show = stripToNil(args.show) or 'dmy' local date = Date(unpack(parms)) if not date then if show == 'format' then return 'error' end return message('mt-need-valid-date') end local add = stripToNil(args.add) if add then for item in add:gmatch('%S+') do date = date + item if not date then return message('mt-cannot-add', item) end end end local sortKey, result local sortable = translateParameters.sortable[args.sortable] if sortable then local value = (date.partial and date.partial.first or date).jdz sortKey = makeSort(value, sortable) end if show ~= 'hide' then result = date[show] if result == nil then result = from_en(date:text(show)) elseif type(result) == 'boolean' then result = result and '1' or '0' else result = from_en(tostring(result)) end end return (sortKey or '') .. makeExtra(args) .. (result or '') end local function rangeJoin(range) -- Return text to be used between a range of ages. return range == 'dash' and '–' or mtext['txt-or'] end local function makeText(values, components, names, options, noUpper) -- Return wikitext representing an age or duration. local text = Collection.new() local count = #values local sep = names.sep or '' for i, v in ipairs(values) do -- v is a number (say 4 for 4 years), or a table ({4,5} for 4 or 5 years). local islist = type(v) == 'table' if (islist or v > 0) or (text.n == 0 and i == count) or (text.n > 0 and components.keepZero) then local fmt, vstr if options.spell then fmt = function(number) return spellNumber(number, options.spell, noUpper or i) end elseif i == 1 and options.format == 'format_commas' then -- Numbers after the first should be small and not need formatting. fmt = formatNumber else fmt = tostring end if islist then vstr = fmt(v[1]) .. rangeJoin(options.range) noUpper = true vstr = vstr .. fmt(v[2]) else vstr = fmt(v) end local name = names[components[i]] if name then if type(name) == 'table' then name = mw.getContentLanguage():plural(islist and v[2] or v, name) end text:add(vstr .. sep .. name) else text:add(vstr) end end end local first, last if options.join == 'sep_space' then first = ' ' last = ' ' elseif options.join == 'sep_comma' then first = ', ' last = ', ' elseif options.join == 'sep_serialcomma' and text.n > 2 then first = ', ' last = mtext['txt-comma-and'] else first = ', ' last = mtext['txt-and'] end for i, v in ipairs(text) do if i < text.n then text[i] = v .. (i + 1 < text.n and first or last) end end local sign = '' if options.isnegative then -- Do not display negative zero. if text.n > 1 or (text.n == 1 and text[1]:sub(1, 1) ~= '0' ) then if options.format == 'format_raw' then sign = '-' -- plain hyphen so result can be used in a calculation else sign = '−' -- Unicode U+2212 MINUS SIGN end end end return (options.sortKey or '') .. (options.extra or '') .. sign .. text:join() .. (options.suffix or '') end local function dateDifference(parms) -- Return a formatted date difference using the given parameters -- which have been validated. local names = { -- Each name is: -- * a string if no plural form of the name is used; or -- * a table of strings, one of which is selected using the rules at -- https://translatewiki.net/wiki/Plural/Mediawiki_plural_rules abbr_off = { sep = '&nbsp;', y = {'year', 'years'}, m = {'month', 'months'}, w = {'week', 'weeks'}, d = {'day', 'days'}, H = {'hour', 'hours'}, M = {'minute', 'minutes'}, S = {'second', 'seconds'}, }, abbr_on = { y = 'y', m = 'm', w = 'w', d = 'd', H = 'h', M = 'm', S = 's', }, abbr_infant = { -- for {{age for infant}} sep = '&nbsp;', y = {'yr', 'yrs'}, m = {'mo', 'mos'}, w = {'wk', 'wks'}, d = {'day', 'days'}, H = {'hr', 'hrs'}, M = {'min', 'mins'}, S = {'sec', 'secs'}, }, abbr_raw = {}, } local diff = parms.diff -- must be a valid date difference local show = parms.show -- may be nil; default is set below local abbr = parms.abbr or 'abbr_off' local defaultJoin if abbr ~= 'abbr_off' then defaultJoin = 'sep_space' end if not show then show = 'ymd' if parms.disp == 'disp_age' then if diff.years < 3 then defaultJoin = 'sep_space' if diff.years >= 1 then show = 'ym' else show = 'md' end else show = 'y' end end end if type(show) ~= 'table' then show = translateParameters.show[show] end if parms.disp == 'disp_raw' then defaultJoin = 'sep_space' abbr = 'abbr_raw' elseif parms.wantSc then defaultJoin = 'sep_serialcomma' end local diffOptions = { round = parms.round, duration = parms.wantDuration, range = parms.range and true or nil, } local sortKey if parms.sortable then local value = diff.age_days + (parms.wantDuration and 1 or 0) -- days and fraction of a day if diff.isnegative then value = -value end sortKey = makeSort(value, parms.sortable) end local textOptions = { extra = parms.extra, format = parms.format, join = parms.sep or defaultJoin, isnegative = diff.isnegative, range = parms.range, sortKey = sortKey, spell = parms.spell, suffix = parms.suffix, -- not currently used } if show.id == 'hide' then return sortKey or '' end local values = { diff:age(show.id, diffOptions) } if values[1] then return makeText(values, show, names[abbr], textOptions) end if diff.partial then -- Handle a more complex range such as -- {{age_yd|20 Dec 2001|2003|range=yes}} → 1 year, 12 days or 2 years, 11 days local opt = { format = textOptions.format, join = textOptions.join, isnegative = textOptions.isnegative, spell = textOptions.spell, } return (textOptions.sortKey or '') .. makeText({ diff.partial.mindiff:age(show.id, diffOptions) }, show, names[abbr], opt) .. rangeJoin(textOptions.range) .. makeText({ diff.partial.maxdiff:age(show.id, diffOptions) }, show, names[abbr], opt, true) .. (textOptions.suffix or '') end return message('mt-bad-show', show.id) end local function getDates(frame, getopt) -- Parse template parameters and return one of: -- * date (a date table, if single) -- * date1, date2 (two date tables, if not single) -- * text (a string error message) -- A missing date is optionally replaced with the current date. -- If wantMixture is true, a missing date component is replaced -- from the current date, so can get a bizarre mixture of -- specified/current y/m/d as has been done by some "age" templates. -- Some results may be placed in table getopt. local Date, currentDate = getExports(frame) getopt = getopt or {} local function flagCurrent(text) -- This allows the calling template to detect if the current date has been used, -- that is, whether both dates have been entered in a template expecting two. -- For example, an infobox may want the age when an event occurred, not the current age. -- Don't bother detecting if wantMixture is used because not needed and it is a poor option. if not text then if getopt.noMissing then return nil -- this gives a nil date which gives an error end text = 'currentdate' if getopt.flag == 'usesCurrent' then getopt.usesCurrent = true end end return text end local args = frame:getParent().args local fields = {} local isNamed = args.year or args.year1 or args.year2 or args.month or args.month1 or args.month2 or args.day or args.day1 or args.day2 if isNamed then fields[1] = args.year1 or args.year fields[2] = args.month1 or args.month fields[3] = args.day1 or args.day fields[4] = args.year2 fields[5] = args.month2 fields[6] = args.day2 else for i = 1, 6 do fields[i] = args[i] end end local imax = 0 for i = 1, 6 do fields[i] = stripToNil(fields[i]) if fields[i] then imax = i end if getopt.omitZero and i % 3 ~= 1 then -- omit zero months and days as unknown values but keep year 0 which is 1 BCE if isZero(fields[i]) then fields[i] = nil getopt.partial = true end end end local fix = getopt.fix and 'fix' or '' local partialText = getopt.partial and 'partial' or '' local dates = {} if isNamed or imax >= 3 then local nrDates = getopt.single and 1 or 2 if getopt.wantMixture then -- Cannot be partial since empty fields are set from current. local components = { 'year', 'month', 'day' } for i = 1, nrDates * 3 do fields[i] = fields[i] or currentDate[components[i > 3 and i - 3 or i]] end for i = 1, nrDates do local index = i == 1 and 1 or 4 local y, m, d = fields[index], fields[index+1], fields[index+2] if (m == 2 or m == '2') and (d == 29 or d == '29') then -- Workaround error with following which attempt to use invalid date 2001-02-29. -- {{age_ymwd|year1=2001|year2=2004|month2=2|day2=29}} -- {{age_ymwd|year1=2001|month1=2|year2=2004|month2=1|day2=29}} -- TODO Get rid of wantMixture because even this ugly code does not handle -- 'Feb' or 'February' or 'feb' or 'february'. if not ((y % 4 == 0 and y % 100 ~= 0) or y % 400 == 0) then d = 28 end end dates[i] = Date(y, m, d) end else -- If partial dates are allowed, accept -- year only, or -- year and month only -- Do not accept year and day without a month because that makes no sense -- (and because, for example, Date('partial', 2001, nil, 12) sets day = nil, not 12). for i = 1, nrDates do local index = i == 1 and 1 or 4 local y, m, d = fields[index], fields[index+1], fields[index+2] if (getopt.partial and y and (m or not d)) or (y and m and d) then dates[i] = Date(fix, partialText, y, m, d) elseif not y and not m and not d then dates[i] = Date(flagCurrent()) end end end else getopt.textdates = true -- have parsed each date from a single text field dates[1] = Date(fix, partialText, flagCurrent(fields[1])) if not getopt.single then dates[2] = Date(fix, partialText, flagCurrent(fields[2])) end end if not dates[1] then return message(getopt.missing1 or 'mt-need-valid-ymd') end if getopt.single then return dates[1] end if not dates[2] then return message(getopt.missing2 or 'mt-need-valid-ymd2') end return dates[1], dates[2] end local function ageGeneric(frame) -- Return the result required by the specified template. -- Can use sortable=x where x = on/table/off/debug in any supported template. -- Some templates default to sortable=on but can be overridden. local name = frame.args.template if not name then return message('mt-template-x') end local args = frame:getParent().args local specs = { age_days = { -- {{age in days}} show = 'd', disp = 'disp_raw', }, age_days_nts = { -- {{age in days nts}} show = 'd', disp = 'disp_raw', format = 'format_commas', sortable = 'on', }, duration_days = { -- {{duration in days}} show = 'd', disp = 'disp_raw', duration = true, }, duration_days_nts = { -- {{duration in days nts}} show = 'd', disp = 'disp_raw', format = 'format_commas', sortable = 'on', duration = true, }, age_full_years = { -- {{age}} show = 'y', abbr = 'abbr_raw', flag = 'usesCurrent', omitZero = true, range = 'dash', }, age_full_years_nts = { -- {{age nts}} show = 'y', abbr = 'abbr_raw', format = 'format_commas', sortable = 'on', }, age_in_years = { -- {{age in years}} show = 'y', abbr = 'abbr_raw', negative = 'error', range = 'dash', }, age_in_years_nts = { -- {{age in years nts}} show = 'y', abbr = 'abbr_raw', negative = 'error', range = 'dash', format = 'format_commas', sortable = 'on', }, age_infant = { -- {{age for infant}} -- Do not set show because special processing is done later. abbr = yes(args.abbr) and 'abbr_infant' or 'abbr_off', disp = 'disp_age', sep = 'sep_space', sortable = 'on', }, age_m = { -- {{age in months}} show = 'm', disp = 'disp_raw', }, age_w = { -- {{age in weeks}} show = 'w', disp = 'disp_raw', }, age_wd = { -- {{age in weeks and days}} show = 'wd', }, age_yd = { -- {{age in years and days}} show = 'yd', format = 'format_commas', sep = args.sep ~= 'and' and 'sep_comma' or nil, }, age_yd_nts = { -- {{age in years and days nts}} show = 'yd', format = 'format_commas', sep = args.sep ~= 'and' and 'sep_comma' or nil, sortable = 'on', }, age_ym = { -- {{age in years and months}} show = 'ym', sep = 'sep_comma', }, age_ymd = { -- {{age in years, months and days}} show = 'ymd', range = true, }, age_ymwd = { -- {{age in years, months, weeks and days}} show = 'ymwd', wantMixture = true, }, } local spec = specs[name] if not spec then return message('mt-template-bad-name') end if name == 'age_days' then local su = stripToNil(args['show unit']) if su then if su == 'abbr' or su == 'full' then spec.disp = nil spec.abbr = su == 'abbr' and 'abbr_on' or nil end end end local partial, autofill local range = stripToNil(args.range) or spec.range if range then -- Suppose partial dates are used and age could be 11 or 12 years. -- "|range=" (empty value) has no effect (spec is used). -- "|range=yes" or spec.range == true sets range = true (gives "11 or 12") -- "|range=dash" or spec.range == 'dash' sets range = 'dash' (gives "11–12"). -- "|range=no" or spec.range == 'no' sets range = nil and fills each date in the diff (gives "12"). -- ("on" is equivalent to "yes", and "off" is equivalent to "no"). -- "|range=OTHER" sets range = nil and rejects partial dates. range = ({ dash = 'dash', off = 'no', no = 'no', [true] = true })[range] or yes(range) if range then partial = true -- accept partial dates with a possible age range for the result if range == 'no' then autofill = true -- missing month/day in first or second date are filled from other date or 1 range = nil end end end local getopt = { fix = yes(args.fix), flag = stripToNil(args.flag) or spec.flag, omitZero = spec.omitZero, partial = partial, wantMixture = spec.wantMixture, } local date1, date2 = getDates(frame, getopt) if type(date1) == 'string' then return date1 end local format = stripToNil(args.format) local spell = spellOptions[format] if format then format = 'format_' .. format elseif name == 'age_days' and getopt.textdates then format = 'format_commas' end local parms = { diff = date2:subtract(date1, { fill = autofill }), wantDuration = spec.duration or yes(args.duration), range = range, wantSc = yes(args.sc), show = args.show == 'hide' and 'hide' or spec.show, abbr = spec.abbr, disp = spec.disp, extra = makeExtra(args, getopt.usesCurrent and format ~= 'format_raw'), format = format or spec.format, round = yes(args.round), sep = spec.sep, sortable = translateParameters.sortable[args.sortable or spec.sortable], spell = spell, } if (spec.negative or frame.args.negative) == 'error' and parms.diff.isnegative then return message('mt-date-wrong-order') end return from_en(dateDifference(parms)) end local function bda(frame) -- Implement [[Template:Birth date and age]]. local args = frame:getParent().args local options = { missing1 = 'mt-need-valid-bd', noMissing = true, single = true, } local date = getDates(frame, options) if type(date) == 'string' then return date -- error text end local Date = getExports(frame) local diff = Date('currentdate') - date if diff.isnegative or diff.years > 150 then return message('mt-invalid-bd-age') end local disp = mtext['txt-bda-disp'] local show = 'y' if diff.years < 2 then disp = 'disp_age' if diff.years == 0 and diff.months == 0 then show = 'd' else show = 'm' end end local result = substituteParameters( mtext['txt-bda'], date:text('%-Y-%m-%d'), from_en(date:text(dateFormat(args))), from_en(dateDifference({ diff = diff, show = show, abbr = 'abbr_off', disp = disp, sep = 'sep_space', })) ) local warnings = tonumber(frame.args.warnings) if warnings and warnings > 0 then local good = { df = true, mf = true, day = true, day1 = true, month = true, month1 = true, year = true, year1 = true, } local invalid local imax = options.textdates and 1 or 3 for k, _ in pairs(args) do if type(k) == 'number' then if k > imax then invalid = tostring(k) break end else if not good[k] then invalid = k break end end end if invalid then result = result .. message('mt-bad-param1', invalid) end end return result end local function dda(frame) -- Implement [[Template:Death date and age]]. local args = frame:getParent().args local options = { missing1 = 'mt-need-valid-dd', missing2 = 'mt-need-valid-bd2', noMissing = true, partial = true, } local date1, date2 = getDates(frame, options) if type(date1) == 'string' then return date1 end local diff = date1 - date2 if diff.isnegative then return message('mt-dd-wrong-order') end local Date = getExports(frame) local today = Date('currentdate') + 1 -- one day in future allows for timezones if date1 > today then return message('mt-dd-future') end local years if diff.partial then years = diff.partial.years years = type(years) == 'table' and years[2] or years else years = diff.years end if years > 150 then return message('mt-invalid-dates-age') end local fmt_date, fmt_ymd if date1.day then -- y, m, d known fmt_date = dateFormat(args) fmt_ymd = '%-Y-%m-%d' elseif date1.month then -- y, m known; d unknown fmt_date = '%B %-Y' fmt_ymd = '%-Y-%m-00' else -- y known; m, d unknown fmt_date = '%-Y' fmt_ymd = '%-Y-00-00' end local sortKey local sortable = translateParameters.sortable[args.sortable] if sortable then local value = (date1.partial and date1.partial.first or date1).jdz sortKey = makeSort(value, sortable) end local result = (sortKey or '') .. substituteParameters( mtext['txt-dda'], date1:text(fmt_ymd), from_en(date1:text(fmt_date)), from_en(dateDifference({ diff = diff, show = 'y', abbr = 'abbr_off', disp = mtext['txt-dda-disp'], range = 'dash', sep = 'sep_space', })) ) local warnings = tonumber(frame.args.warnings) if warnings and warnings > 0 then local good = { df = true, mf = true, } local invalid local imax = options.textdates and 2 or 6 for k, _ in pairs(args) do if type(k) == 'number' then if k > imax then invalid = tostring(k) break end else if not good[k] then invalid = k break end end end if invalid then result = result .. message('mt-bad-param1', invalid) end end return result end local function dateToGsd(frame) -- Implement [[Template:Gregorian serial date]]. -- Return Gregorian serial date of the given date, or the current date. -- The returned value is negative for dates before 1 January 1 AD -- despite the fact that GSD is not defined for such dates. local date = getDates(frame, { wantMixture=true, single=true }) if type(date) == 'string' then return date end return tostring(date.gsd) end local function jdToDate(frame) -- Return formatted date from a Julian date. -- The result includes a time if the input includes a fraction. -- The word 'Julian' is accepted for the Julian calendar. local Date = getExports(frame) local args = frame:getParent().args local date = Date('juliandate', args[1], args[2]) if date then return from_en(date:text()) end return message('mt-need-jdn') end local function dateToJd(frame) -- Return Julian date (a number) from a date which may include a time, -- or the current date ('currentdate') or current date and time ('currentdatetime'). -- The word 'Julian' is accepted for the Julian calendar. local Date = getExports(frame) local args = frame:getParent().args local date = Date(args[1], args[2], args[3], args[4], args[5], args[6], args[7]) if date then return tostring(date.jd) end return message('mt-need-valid-ymd-current') end local function timeInterval(frame) -- Implement [[Template:Time interval]]. -- There are two positional arguments: date1, date2. -- The default for each is the current date and time. -- Result is date2 - date1 formatted. local Date = getExports(frame) local args = frame:getParent().args local parms = { extra = makeExtra(args), wantDuration = yes(args.duration), range = yes(args.range) or (args.range == 'dash' and 'dash' or nil), wantSc = yes(args.sc), } local fix = yes(args.fix) and 'fix' or '' local date1 = Date(fix, 'partial', stripToNil(args[1]) or 'currentdatetime') if not date1 then return message('mt-invalid-start') end local date2 = Date(fix, 'partial', stripToNil(args[2]) or 'currentdatetime') if not date2 then return message('mt-invalid-end') end parms.diff = date2 - date1 for argname, translate in pairs(translateParameters) do local parm = stripToNil(args[argname]) if parm then parm = translate[parm] if parm == nil then -- test for nil because false is a valid setting return message('mt-bad-param2', argname, args[argname]) end parms[argname] = parm end end if parms.round then local round = parms.round local show = parms.show if round ~= 'on' then if show then if show.id ~= round then return message('mt-conflicting-show', args.show, args.round) end else parms.show = translateParameters.show[round] end end parms.round = true end return from_en(dateDifference(parms)) end return { age_generic = ageGeneric, -- can emulate several age templates birth_date_and_age = bda, -- Template:Birth_date_and_age death_date_and_age = dda, -- Template:Death_date_and_age gsd = dateToGsd, -- Template:Gregorian_serial_date extract = dateExtract, -- Template:Extract jd_to_date = jdToDate, -- Template:? JULIANDAY = dateToJd, -- Template:JULIANDAY time_interval = timeInterval, -- Template:Time_interval } 094ef43a81ac2366c838b6ad889ed0ffe5a1eec4 มอดูล:Yesno 828 44 74 2023-10-05T12:42:57Z PeachFullzZ 2 สร้างหน้าด้วย "-- Function allowing for consistent treatment of boolean-like wikitext input. -- It works similarly to the template {{yesno}}. return function (val, default) -- If your wiki uses non-ascii characters for any of "yes", "no", etc., you -- should replace "val:lower()" with "mw.ustring.lower(val)" in the -- following line. val = type(val) == 'string' and val:lower() or val if val == nil then return nil elseif val == true or val == 'yes' or..." Scribunto text/plain -- Function allowing for consistent treatment of boolean-like wikitext input. -- It works similarly to the template {{yesno}}. return function (val, default) -- If your wiki uses non-ascii characters for any of "yes", "no", etc., you -- should replace "val:lower()" with "mw.ustring.lower(val)" in the -- following line. val = type(val) == 'string' and val:lower() or val if val == nil then return nil elseif val == true or val == 'yes' or val == 'y' or val == 'true' or val == 't' or val == 'on' or tonumber(val) == 1 then return true elseif val == false or val == 'no' or val == 'n' or val == 'false' or val == 'f' or val == 'off' or tonumber(val) == 0 then return false else return default end end f767643e7d12126d020d88d662a3dd057817b9dc 75 74 2023-10-05T12:43:13Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Yesno]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- Function allowing for consistent treatment of boolean-like wikitext input. -- It works similarly to the template {{yesno}}. return function (val, default) -- If your wiki uses non-ascii characters for any of "yes", "no", etc., you -- should replace "val:lower()" with "mw.ustring.lower(val)" in the -- following line. val = type(val) == 'string' and val:lower() or val if val == nil then return nil elseif val == true or val == 'yes' or val == 'y' or val == 'true' or val == 't' or val == 'on' or tonumber(val) == 1 then return true elseif val == false or val == 'no' or val == 'n' or val == 'false' or val == 'f' or val == 'off' or tonumber(val) == 0 then return false else return default end end f767643e7d12126d020d88d662a3dd057817b9dc แม่แบบ:อายุปีและวัน/วัน 10 45 76 2023-10-05T12:46:46Z PeachFullzZ 2 สร้างหน้าด้วย "{{nts|{{{1}}}}} {{#ifeq: {{{1}}}|1|วัน|วัน}}" wikitext text/x-wiki {{nts|{{{1}}}}} {{#ifeq: {{{1}}}|1|วัน|วัน}} 4a3906f5f62aa5f368f38be4702c832c51561aef 77 76 2023-10-05T12:47:17Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:อายุปีและวัน/วัน]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki {{nts|{{{1}}}}} {{#ifeq: {{{1}}}|1|วัน|วัน}} 4a3906f5f62aa5f368f38be4702c832c51561aef แม่แบบ:Age in days 10 46 78 2023-10-05T12:48:17Z PeachFullzZ 2 สร้างหน้าด้วย "<includeonly>{{#expr: + {{Gregorian serial date |month = {{{month2|{{{5|{{CURRENTMONTH}}}}}}}} |day = {{{day2|{{{6|{{CURRENTDAY}}}}}}}} |year = {{{year2|{{{4|{{CURRENTYEAR}}}}}}}} }} - {{Gregorian serial date |month = {{{month1|{{{2|{{CURRENTMONTH}}}}}}}} |day = {{{day1|{{{3|{{CURRENTDAY}}}}}}}}..." wikitext text/x-wiki <includeonly>{{#expr: + {{Gregorian serial date |month = {{{month2|{{{5|{{CURRENTMONTH}}}}}}}} |day = {{{day2|{{{6|{{CURRENTDAY}}}}}}}} |year = {{{year2|{{{4|{{CURRENTYEAR}}}}}}}} }} - {{Gregorian serial date |month = {{{month1|{{{2|{{CURRENTMONTH}}}}}}}} |day = {{{day1|{{{3|{{CURRENTDAY}}}}}}}} |year = {{{year1|{{{1|{{CURRENTYEAR}}}}}}}} }} }}</includeonly><noinclude>{{Documentation}}</noinclude> 0523a43b75846624f102c8cc03bec1c23f5b1e9e แม่แบบ:Yesno 10 47 79 2023-10-05T12:56:10Z PeachFullzZ 2 สร้างหน้าด้วย "{{<includeonly>safesubst:</includeonly>#switch: {{<includeonly>safesubst:</includeonly>lc: {{{1|¬}}} }} |no |n |f |false |off |0 = {{{no|<!-- null -->}}} | = {{{blank|{{{no|<!-- null -->}}}}}} |¬ = {{{¬|}}} |yes |y |t |true |on |1 = {{{yes|yes}}} |#default = {{{def|{{{yes|yes}}}}}} }}<noinclude> {{Documentation}} </noinclude>" wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#switch: {{<includeonly>safesubst:</includeonly>lc: {{{1|¬}}} }} |no |n |f |false |off |0 = {{{no|<!-- null -->}}} | = {{{blank|{{{no|<!-- null -->}}}}}} |¬ = {{{¬|}}} |yes |y |t |true |on |1 = {{{yes|yes}}} |#default = {{{def|{{{yes|yes}}}}}} }}<noinclude> {{Documentation}} </noinclude> 629c2937bc5cf7cfe13cd2a598582af832782399 มอดูล:Namespace detect/config 828 48 80 2023-10-05T13:18:40Z PeachFullzZ 2 สร้างหน้าด้วย "-------------------------------------------------------------------------------- -- Namespace detect configuration data -- -- -- -- This module stores configuration data for Module:Namespace detect. Here -- -- you can localise the module to your wiki's language. -- --..." Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect configuration data -- -- -- -- This module stores configuration data for Module:Namespace detect. Here -- -- you can localise the module to your wiki's language. -- -- -- -- To activate a configuration item, you need to uncomment it. This means -- -- that you need to remove the text "-- " at the start of the line. -- -------------------------------------------------------------------------------- local cfg = {} -- Don't edit this line. -------------------------------------------------------------------------------- -- Parameter names -- -- These configuration items specify custom parameter names. Values added -- -- here will work in addition to the default English parameter names. -- -- To add one extra name, you can use this format: -- -- -- -- cfg.foo = 'parameter name' -- -- -- -- To add multiple names, you can use this format: -- -- -- -- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} -- -------------------------------------------------------------------------------- ---- This parameter displays content for the main namespace: -- cfg.main = 'main' ---- This parameter displays in talk namespaces: -- cfg.talk = 'talk' ---- This parameter displays content for "other" namespaces (namespaces for which ---- parameters have not been specified): -- cfg.other = 'other' ---- This parameter makes talk pages behave as though they are the corresponding ---- subject namespace. Note that this parameter is used with [[Module:Yesno]]. ---- Edit that module to change the default values of "yes", "no", etc. -- cfg.subjectns = 'subjectns' ---- This parameter sets a demonstration namespace: -- cfg.demospace = 'demospace' ---- This parameter sets a specific page to compare: cfg.demopage = 'page' -------------------------------------------------------------------------------- -- Table configuration -- -- These configuration items allow customisation of the "table" function, -- -- used to generate a table of possible parameters in the module -- -- documentation. -- -------------------------------------------------------------------------------- ---- The header for the namespace column in the wikitable containing the list of ---- possible subject-space parameters. -- cfg.wikitableNamespaceHeader = 'Namespace' ---- The header for the wikitable containing the list of possible subject-space ---- parameters. -- cfg.wikitableAliasesHeader = 'Aliases' -------------------------------------------------------------------------------- -- End of configuration data -- -------------------------------------------------------------------------------- return cfg -- Don't edit this line. 0e4ff08d13c4b664d66b32c232deb129b77c1a56 81 80 2023-10-05T13:18:57Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Namespace detect/config]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect configuration data -- -- -- -- This module stores configuration data for Module:Namespace detect. Here -- -- you can localise the module to your wiki's language. -- -- -- -- To activate a configuration item, you need to uncomment it. This means -- -- that you need to remove the text "-- " at the start of the line. -- -------------------------------------------------------------------------------- local cfg = {} -- Don't edit this line. -------------------------------------------------------------------------------- -- Parameter names -- -- These configuration items specify custom parameter names. Values added -- -- here will work in addition to the default English parameter names. -- -- To add one extra name, you can use this format: -- -- -- -- cfg.foo = 'parameter name' -- -- -- -- To add multiple names, you can use this format: -- -- -- -- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} -- -------------------------------------------------------------------------------- ---- This parameter displays content for the main namespace: -- cfg.main = 'main' ---- This parameter displays in talk namespaces: -- cfg.talk = 'talk' ---- This parameter displays content for "other" namespaces (namespaces for which ---- parameters have not been specified): -- cfg.other = 'other' ---- This parameter makes talk pages behave as though they are the corresponding ---- subject namespace. Note that this parameter is used with [[Module:Yesno]]. ---- Edit that module to change the default values of "yes", "no", etc. -- cfg.subjectns = 'subjectns' ---- This parameter sets a demonstration namespace: -- cfg.demospace = 'demospace' ---- This parameter sets a specific page to compare: cfg.demopage = 'page' -------------------------------------------------------------------------------- -- Table configuration -- -- These configuration items allow customisation of the "table" function, -- -- used to generate a table of possible parameters in the module -- -- documentation. -- -------------------------------------------------------------------------------- ---- The header for the namespace column in the wikitable containing the list of ---- possible subject-space parameters. -- cfg.wikitableNamespaceHeader = 'Namespace' ---- The header for the wikitable containing the list of possible subject-space ---- parameters. -- cfg.wikitableAliasesHeader = 'Aliases' -------------------------------------------------------------------------------- -- End of configuration data -- -------------------------------------------------------------------------------- return cfg -- Don't edit this line. 0e4ff08d13c4b664d66b32c232deb129b77c1a56 มอดูล:Namespace detect 828 49 82 2023-10-05T13:19:31Z PeachFullzZ 2 สร้างหน้าด้วย "--[[ -------------------------------------------------------------------------------- -- -- -- NAMESPACE DETECT -- -- -- -- This module implements the {{namespace detect}} template in Lua, with a -- -- few improvements: all namespaces and all..." Scribunto text/plain --[[ -------------------------------------------------------------------------------- -- -- -- NAMESPACE DETECT -- -- -- -- This module implements the {{namespace detect}} template in Lua, with a -- -- few improvements: all namespaces and all namespace aliases are supported, -- -- and namespace names are detected automatically for the local wiki. The -- -- module can also use the corresponding subject namespace value if it is -- -- used on a talk page. Parameter names can be configured for different wikis -- -- by altering the values in the "cfg" table in -- -- Module:Namespace detect/config. -- -- -- -------------------------------------------------------------------------------- --]] local data = mw.loadData('Module:Namespace detect/data') local argKeys = data.argKeys local cfg = data.cfg local mappings = data.mappings local yesno = require('Module:Yesno') local mArguments -- Lazily initialise Module:Arguments local mTableTools -- Lazily initilalise Module:TableTools local ustringLower = mw.ustring.lower local p = {} local function fetchValue(t1, t2) -- Fetches a value from the table t1 for the first key in array t2 where -- a non-nil value of t1 exists. for i, key in ipairs(t2) do local value = t1[key] if value ~= nil then return value end end return nil end local function equalsArrayValue(t, value) -- Returns true if value equals a value in the array t. Otherwise -- returns false. for i, arrayValue in ipairs(t) do if value == arrayValue then return true end end return false end function p.getPageObject(page) -- Get the page object, passing the function through pcall in case of -- errors, e.g. being over the expensive function count limit. if page then local success, pageObject = pcall(mw.title.new, page) if success then return pageObject else return nil end else return mw.title.getCurrentTitle() end end -- Provided for backward compatibility with other modules function p.getParamMappings() return mappings end local function getNamespace(args) -- This function gets the namespace name from the page object. local page = fetchValue(args, argKeys.demopage) if page == '' then page = nil end local demospace = fetchValue(args, argKeys.demospace) if demospace == '' then demospace = nil end local subjectns = fetchValue(args, argKeys.subjectns) local ret if demospace then -- Handle "demospace = main" properly. if equalsArrayValue(argKeys.main, ustringLower(demospace)) then ret = mw.site.namespaces[0].name else ret = demospace end else local pageObject = p.getPageObject(page) if pageObject then if pageObject.isTalkPage then -- Get the subject namespace if the option is set, -- otherwise use "talk". if yesno(subjectns) then ret = mw.site.namespaces[pageObject.namespace].subject.name else ret = 'talk' end else ret = pageObject.nsText end else return nil -- return nil if the page object doesn't exist. end end ret = ret:gsub('_', ' ') return ustringLower(ret) end function p._main(args) -- Check the parameters stored in the mappings table for any matches. local namespace = getNamespace(args) or 'other' -- "other" avoids nil table keys local params = mappings[namespace] or {} local ret = fetchValue(args, params) --[[ -- If there were no matches, return parameters for other namespaces. -- This happens if there was no text specified for the namespace that -- was detected or if the demospace parameter is not a valid -- namespace. Note that the parameter for the detected namespace must be -- completely absent for this to happen, not merely blank. --]] if ret == nil then ret = fetchValue(args, argKeys.other) end return ret end function p.main(frame) mArguments = require('Module:Arguments') local args = mArguments.getArgs(frame, {removeBlanks = false}) local ret = p._main(args) return ret or '' end function p.table(frame) --[[ -- Create a wikitable of all subject namespace parameters, for -- documentation purposes. The talk parameter is optional, in case it -- needs to be excluded in the documentation. --]] -- Load modules and initialise variables. mTableTools = require('Module:TableTools') local namespaces = mw.site.namespaces local cfg = data.cfg local useTalk = type(frame) == 'table' and type(frame.args) == 'table' and yesno(frame.args.talk) -- Whether to use the talk parameter. -- Get the header names. local function checkValue(value, default) if type(value) == 'string' then return value else return default end end local nsHeader = checkValue(cfg.wikitableNamespaceHeader, 'Namespace') local aliasesHeader = checkValue(cfg.wikitableAliasesHeader, 'Aliases') -- Put the namespaces in order. local mappingsOrdered = {} for nsname, params in pairs(mappings) do if useTalk or nsname ~= 'talk' then local nsid = namespaces[nsname].id -- Add 1, as the array must start with 1; nsid 0 would be lost otherwise. nsid = nsid + 1 mappingsOrdered[nsid] = params end end mappingsOrdered = mTableTools.compressSparseArray(mappingsOrdered) -- Build the table. local ret = '{| class="wikitable"' .. '\n|-' .. '\n! ' .. nsHeader .. '\n! ' .. aliasesHeader for i, params in ipairs(mappingsOrdered) do for j, param in ipairs(params) do if j == 1 then ret = ret .. '\n|-' .. '\n| <code>' .. param .. '</code>' .. '\n| ' elseif j == 2 then ret = ret .. '<code>' .. param .. '</code>' else ret = ret .. ', <code>' .. param .. '</code>' end end end ret = ret .. '\n|-' .. '\n|}' return ret end return p a4757000273064f151f0f22dc0e139092e5ff443 83 82 2023-10-05T13:19:45Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Namespace detect]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain --[[ -------------------------------------------------------------------------------- -- -- -- NAMESPACE DETECT -- -- -- -- This module implements the {{namespace detect}} template in Lua, with a -- -- few improvements: all namespaces and all namespace aliases are supported, -- -- and namespace names are detected automatically for the local wiki. The -- -- module can also use the corresponding subject namespace value if it is -- -- used on a talk page. Parameter names can be configured for different wikis -- -- by altering the values in the "cfg" table in -- -- Module:Namespace detect/config. -- -- -- -------------------------------------------------------------------------------- --]] local data = mw.loadData('Module:Namespace detect/data') local argKeys = data.argKeys local cfg = data.cfg local mappings = data.mappings local yesno = require('Module:Yesno') local mArguments -- Lazily initialise Module:Arguments local mTableTools -- Lazily initilalise Module:TableTools local ustringLower = mw.ustring.lower local p = {} local function fetchValue(t1, t2) -- Fetches a value from the table t1 for the first key in array t2 where -- a non-nil value of t1 exists. for i, key in ipairs(t2) do local value = t1[key] if value ~= nil then return value end end return nil end local function equalsArrayValue(t, value) -- Returns true if value equals a value in the array t. Otherwise -- returns false. for i, arrayValue in ipairs(t) do if value == arrayValue then return true end end return false end function p.getPageObject(page) -- Get the page object, passing the function through pcall in case of -- errors, e.g. being over the expensive function count limit. if page then local success, pageObject = pcall(mw.title.new, page) if success then return pageObject else return nil end else return mw.title.getCurrentTitle() end end -- Provided for backward compatibility with other modules function p.getParamMappings() return mappings end local function getNamespace(args) -- This function gets the namespace name from the page object. local page = fetchValue(args, argKeys.demopage) if page == '' then page = nil end local demospace = fetchValue(args, argKeys.demospace) if demospace == '' then demospace = nil end local subjectns = fetchValue(args, argKeys.subjectns) local ret if demospace then -- Handle "demospace = main" properly. if equalsArrayValue(argKeys.main, ustringLower(demospace)) then ret = mw.site.namespaces[0].name else ret = demospace end else local pageObject = p.getPageObject(page) if pageObject then if pageObject.isTalkPage then -- Get the subject namespace if the option is set, -- otherwise use "talk". if yesno(subjectns) then ret = mw.site.namespaces[pageObject.namespace].subject.name else ret = 'talk' end else ret = pageObject.nsText end else return nil -- return nil if the page object doesn't exist. end end ret = ret:gsub('_', ' ') return ustringLower(ret) end function p._main(args) -- Check the parameters stored in the mappings table for any matches. local namespace = getNamespace(args) or 'other' -- "other" avoids nil table keys local params = mappings[namespace] or {} local ret = fetchValue(args, params) --[[ -- If there were no matches, return parameters for other namespaces. -- This happens if there was no text specified for the namespace that -- was detected or if the demospace parameter is not a valid -- namespace. Note that the parameter for the detected namespace must be -- completely absent for this to happen, not merely blank. --]] if ret == nil then ret = fetchValue(args, argKeys.other) end return ret end function p.main(frame) mArguments = require('Module:Arguments') local args = mArguments.getArgs(frame, {removeBlanks = false}) local ret = p._main(args) return ret or '' end function p.table(frame) --[[ -- Create a wikitable of all subject namespace parameters, for -- documentation purposes. The talk parameter is optional, in case it -- needs to be excluded in the documentation. --]] -- Load modules and initialise variables. mTableTools = require('Module:TableTools') local namespaces = mw.site.namespaces local cfg = data.cfg local useTalk = type(frame) == 'table' and type(frame.args) == 'table' and yesno(frame.args.talk) -- Whether to use the talk parameter. -- Get the header names. local function checkValue(value, default) if type(value) == 'string' then return value else return default end end local nsHeader = checkValue(cfg.wikitableNamespaceHeader, 'Namespace') local aliasesHeader = checkValue(cfg.wikitableAliasesHeader, 'Aliases') -- Put the namespaces in order. local mappingsOrdered = {} for nsname, params in pairs(mappings) do if useTalk or nsname ~= 'talk' then local nsid = namespaces[nsname].id -- Add 1, as the array must start with 1; nsid 0 would be lost otherwise. nsid = nsid + 1 mappingsOrdered[nsid] = params end end mappingsOrdered = mTableTools.compressSparseArray(mappingsOrdered) -- Build the table. local ret = '{| class="wikitable"' .. '\n|-' .. '\n! ' .. nsHeader .. '\n! ' .. aliasesHeader for i, params in ipairs(mappingsOrdered) do for j, param in ipairs(params) do if j == 1 then ret = ret .. '\n|-' .. '\n| <code>' .. param .. '</code>' .. '\n| ' elseif j == 2 then ret = ret .. '<code>' .. param .. '</code>' else ret = ret .. ', <code>' .. param .. '</code>' end end end ret = ret .. '\n|-' .. '\n|}' return ret end return p a4757000273064f151f0f22dc0e139092e5ff443 มอดูล:Namespace detect/data 828 50 84 2023-10-05T13:20:22Z PeachFullzZ 2 สร้างหน้าด้วย "-------------------------------------------------------------------------------- -- Namespace detect data -- -- This module holds data for [[Module:Namespace detect]] to be loaded per -- -- page, rather than per #invoke, for performance reasons. -- -------------------------------------------------------------------------------- local cfg = require('Module:Namespace detect/co..." Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect data -- -- This module holds data for [[Module:Namespace detect]] to be loaded per -- -- page, rather than per #invoke, for performance reasons. -- -------------------------------------------------------------------------------- local cfg = require('Module:Namespace detect/config') local function addKey(t, key, defaultKey) if key ~= defaultKey then t[#t + 1] = key end end -- Get a table of parameters to query for each default parameter name. -- This allows wikis to customise parameter names in the cfg table while -- ensuring that default parameter names will always work. The cfg table -- values can be added as a string, or as an array of strings. local defaultKeys = { 'main', 'talk', 'other', 'subjectns', 'demospace', 'demopage' } local argKeys = {} for i, defaultKey in ipairs(defaultKeys) do argKeys[defaultKey] = {defaultKey} end for defaultKey, t in pairs(argKeys) do local cfgValue = cfg[defaultKey] local cfgValueType = type(cfgValue) if cfgValueType == 'string' then addKey(t, cfgValue, defaultKey) elseif cfgValueType == 'table' then for i, key in ipairs(cfgValue) do addKey(t, key, defaultKey) end end cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more. end local function getParamMappings() --[[ -- Returns a table of how parameter names map to namespace names. The keys -- are the actual namespace names, in lower case, and the values are the -- possible parameter names for that namespace, also in lower case. The -- table entries are structured like this: -- { -- [''] = {'main'}, -- ['wikipedia'] = {'wikipedia', 'project', 'wp'}, -- ... -- } --]] local mappings = {} local mainNsName = mw.site.subjectNamespaces[0].name mainNsName = mw.ustring.lower(mainNsName) mappings[mainNsName] = mw.clone(argKeys.main) mappings['talk'] = mw.clone(argKeys.talk) for nsid, ns in pairs(mw.site.subjectNamespaces) do if nsid ~= 0 then -- Exclude main namespace. local nsname = mw.ustring.lower(ns.name) local canonicalName = mw.ustring.lower(ns.canonicalName) mappings[nsname] = {nsname} if canonicalName ~= nsname then table.insert(mappings[nsname], canonicalName) end for _, alias in ipairs(ns.aliases) do table.insert(mappings[nsname], mw.ustring.lower(alias)) end end end return mappings end return { argKeys = argKeys, cfg = cfg, mappings = getParamMappings() } d224f42a258bc308ef3ad8cc8686cd7a4f47d005 มอดูล:Unsubst 828 51 85 2023-10-05T13:21:50Z PeachFullzZ 2 สร้างหน้าด้วย "local checkType = require('libraryUtil').checkType local p = {} local BODY_PARAM = '$B' local specialParams = { ['$params'] = 'parameter list', ['$aliases'] = 'parameter aliases', ['$flags'] = 'flags', ['$B'] = 'template content', ['$template-name'] = 'template invocation name override', } function p.main(frame, body) -- If we are substing, this function returns a template invocation, and if -- not, it returns the template body. The templ..." Scribunto text/plain local checkType = require('libraryUtil').checkType local p = {} local BODY_PARAM = '$B' local specialParams = { ['$params'] = 'parameter list', ['$aliases'] = 'parameter aliases', ['$flags'] = 'flags', ['$B'] = 'template content', ['$template-name'] = 'template invocation name override', } function p.main(frame, body) -- If we are substing, this function returns a template invocation, and if -- not, it returns the template body. The template body can be specified in -- the body parameter, or in the template parameter defined in the -- BODY_PARAM variable. This function can be called from Lua or from -- #invoke. -- Return the template body if we aren't substing. if not mw.isSubsting() then if body ~= nil then return body elseif frame.args[BODY_PARAM] ~= nil then return frame.args[BODY_PARAM] else error(string.format( "no template content specified (use parameter '%s' from #invoke)", BODY_PARAM ), 2) end end -- Sanity check for the frame object. if type(frame) ~= 'table' or type(frame.getParent) ~= 'function' or not frame:getParent() then error( "argument #1 to 'main' must be a frame object with a parent " .. "frame available", 2 ) end -- Find the invocation name. local mTemplateInvocation = require('Module:Template invocation') local name if frame.args['$template-name'] and '' ~= frame.args['$template-name'] then name = frame.args['$template-name'] -- override whatever the template name is with this name else name = mTemplateInvocation.name(frame:getParent():getTitle()) end -- Combine passed args with passed defaults local args = {} if string.find( ','..(frame.args['$flags'] or '')..',', ',%s*override%s*,' ) then for k, v in pairs( frame:getParent().args ) do args[k] = v end for k, v in pairs( frame.args ) do if not specialParams[k] then if v == '__DATE__' then v = mw.getContentLanguage():formatDate( 'F Y' ) end args[k] = v end end else for k, v in pairs( frame.args ) do if not specialParams[k] then if v == '__DATE__' then v = mw.getContentLanguage():formatDate( 'F Y' ) end args[k] = v end end for k, v in pairs( frame:getParent().args ) do args[k] = v end end -- Trim parameters, if not specified otherwise if not string.find( ','..(frame.args['$flags'] or '')..',', ',%s*keep%-whitespace%s*,' ) then for k, v in pairs( args ) do args[k] = mw.ustring.match(v, '^%s*(.*)%s*$') or '' end end -- Pull information from parameter aliases local aliases = {} if frame.args['$aliases'] then local list = mw.text.split( frame.args['$aliases'], '%s*,%s*' ) for k, v in ipairs( list ) do local tmp = mw.text.split( v, '%s*>%s*' ) aliases[tonumber(mw.ustring.match(tmp[1], '^[1-9][0-9]*$')) or tmp[1]] = ((tonumber(mw.ustring.match(tmp[2], '^[1-9][0-9]*$'))) or tmp[2]) end end for k, v in pairs( aliases ) do if args[k] and ( not args[v] or args[v] == '' ) then args[v] = args[k] end args[k] = nil end -- Remove empty parameters, if specified if string.find( ','..(frame.args['$flags'] or '')..',', ',%s*remove%-empty%s*,' ) then local tmp = 0 for k, v in ipairs( args ) do if v ~= '' or ( args[k+1] and args[k+1] ~= '' ) or ( args[k+2] and args[k+2] ~= '' ) then tmp = k else break end end for k, v in pairs( args ) do if v == '' then if not (type(k) == 'number' and k < tmp) then args[k] = nil end end end end -- Order parameters if frame.args['$params'] then local params, tmp = mw.text.split( frame.args['$params'], '%s*,%s*' ), {} for k, v in ipairs(params) do v = tonumber(mw.ustring.match(v, '^[1-9][0-9]*$')) or v if args[v] then tmp[v], args[v] = args[v], nil end end for k, v in pairs(args) do tmp[k], args[k] = args[k], nil end args = tmp end return mTemplateInvocation.invocation(name, args) end p[''] = p.main -- For backwards compatibility return p 7f01ffc8aa2ac4a4772f14c12e0b77e384ecabb6 86 85 2023-10-05T13:22:04Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Unsubst]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local checkType = require('libraryUtil').checkType local p = {} local BODY_PARAM = '$B' local specialParams = { ['$params'] = 'parameter list', ['$aliases'] = 'parameter aliases', ['$flags'] = 'flags', ['$B'] = 'template content', ['$template-name'] = 'template invocation name override', } function p.main(frame, body) -- If we are substing, this function returns a template invocation, and if -- not, it returns the template body. The template body can be specified in -- the body parameter, or in the template parameter defined in the -- BODY_PARAM variable. This function can be called from Lua or from -- #invoke. -- Return the template body if we aren't substing. if not mw.isSubsting() then if body ~= nil then return body elseif frame.args[BODY_PARAM] ~= nil then return frame.args[BODY_PARAM] else error(string.format( "no template content specified (use parameter '%s' from #invoke)", BODY_PARAM ), 2) end end -- Sanity check for the frame object. if type(frame) ~= 'table' or type(frame.getParent) ~= 'function' or not frame:getParent() then error( "argument #1 to 'main' must be a frame object with a parent " .. "frame available", 2 ) end -- Find the invocation name. local mTemplateInvocation = require('Module:Template invocation') local name if frame.args['$template-name'] and '' ~= frame.args['$template-name'] then name = frame.args['$template-name'] -- override whatever the template name is with this name else name = mTemplateInvocation.name(frame:getParent():getTitle()) end -- Combine passed args with passed defaults local args = {} if string.find( ','..(frame.args['$flags'] or '')..',', ',%s*override%s*,' ) then for k, v in pairs( frame:getParent().args ) do args[k] = v end for k, v in pairs( frame.args ) do if not specialParams[k] then if v == '__DATE__' then v = mw.getContentLanguage():formatDate( 'F Y' ) end args[k] = v end end else for k, v in pairs( frame.args ) do if not specialParams[k] then if v == '__DATE__' then v = mw.getContentLanguage():formatDate( 'F Y' ) end args[k] = v end end for k, v in pairs( frame:getParent().args ) do args[k] = v end end -- Trim parameters, if not specified otherwise if not string.find( ','..(frame.args['$flags'] or '')..',', ',%s*keep%-whitespace%s*,' ) then for k, v in pairs( args ) do args[k] = mw.ustring.match(v, '^%s*(.*)%s*$') or '' end end -- Pull information from parameter aliases local aliases = {} if frame.args['$aliases'] then local list = mw.text.split( frame.args['$aliases'], '%s*,%s*' ) for k, v in ipairs( list ) do local tmp = mw.text.split( v, '%s*>%s*' ) aliases[tonumber(mw.ustring.match(tmp[1], '^[1-9][0-9]*$')) or tmp[1]] = ((tonumber(mw.ustring.match(tmp[2], '^[1-9][0-9]*$'))) or tmp[2]) end end for k, v in pairs( aliases ) do if args[k] and ( not args[v] or args[v] == '' ) then args[v] = args[k] end args[k] = nil end -- Remove empty parameters, if specified if string.find( ','..(frame.args['$flags'] or '')..',', ',%s*remove%-empty%s*,' ) then local tmp = 0 for k, v in ipairs( args ) do if v ~= '' or ( args[k+1] and args[k+1] ~= '' ) or ( args[k+2] and args[k+2] ~= '' ) then tmp = k else break end end for k, v in pairs( args ) do if v == '' then if not (type(k) == 'number' and k < tmp) then args[k] = nil end end end end -- Order parameters if frame.args['$params'] then local params, tmp = mw.text.split( frame.args['$params'], '%s*,%s*' ), {} for k, v in ipairs(params) do v = tonumber(mw.ustring.match(v, '^[1-9][0-9]*$')) or v if args[v] then tmp[v], args[v] = args[v], nil end end for k, v in pairs(args) do tmp[k], args[k] = args[k], nil end args = tmp end return mTemplateInvocation.invocation(name, args) end p[''] = p.main -- For backwards compatibility return p 7f01ffc8aa2ac4a4772f14c12e0b77e384ecabb6 มอดูล:Random 828 52 87 2023-10-05T13:25:10Z PeachFullzZ 2 สร้างหน้าด้วย "-- This module contains a number of functions that make use of random numbers. local cfg = {} -------------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------------- -- Set this to true if your wiki has a traffic rate of less than one edit every two minutes or so. -- This will prevent the same "random" number being generated many..." Scribunto text/plain -- This module contains a number of functions that make use of random numbers. local cfg = {} -------------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------------- -- Set this to true if your wiki has a traffic rate of less than one edit every two minutes or so. -- This will prevent the same "random" number being generated many times in a row until a new edit is made -- to the wiki. This setting is only relevant if the |same= parameter is set. cfg.lowTraffic = false -- If cfg.lowTraffic is set to true, and the |same= parameter is set, this value is used for the refresh rate of the random seed. -- This is the number of seconds until the seed is changed. Getting this right is tricky. If you set it too high, the same number -- will be returned many times in a row. If you set it too low, you may get different random numbers appearing on the same page, -- particularly for pages that take many seconds to process. cfg.seedRefreshRate = 60 -------------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------------- local p = {} -- For functions available from other Lua modules. local l = {} -- For functions not available from other Lua modules, but that need to be accessed using table keys. local yesno = require('Module:Yesno') local makeList = require('Module:List').makeList -------------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------------- local function raiseError(msg) -- This helps to generate a wikitext error. It is the calling function's responsibility as to how to include it in the output. return mw.ustring.format('<b class="error">[[Module:Random]] error: %s.</b>', msg) end -------------------------------------------------------------------------------------- -- random number function -------------------------------------------------------------------------------------- local function getBigRandom(l, u) -- Gets a random integer between l and u, and is not limited to RAND_MAX. local r = 0 local n = 2^math.random(30) -- Any power of 2. local limit = math.ceil(53 / (math.log(n) / math.log(2))) for i = 1, limit do r = r + math.random(0, n - 1) / (n^i) end return math.floor(r * (u - l + 1)) + l end function l.number(args) -- Gets a random number. first = tonumber(args[1]) second = tonumber(args[2]) -- This needs to use if statements as math.random won't accept explicit nil values as arguments. if first then if second then if first > second then -- Second number cannot be less than the first, or it causes an error. first, second = second, first end return getBigRandom(first, second) else return getBigRandom(1, first) end else return math.random() end end -------------------------------------------------------------------------------------- -- Date function -------------------------------------------------------------------------------------- function l.date(args) -- This function gets random dates, and takes timestamps as positional arguments. -- With no arguments specified, it outputs a random date in the current year. -- With two arguments specified, it outputs a random date between the timestamps. -- With one argument specified, the date is a random date between the unix epoch (1 Jan 1970) and the timestamp. -- The output can be formatted using the "format" argument, which works in the same way as the #time parser function. -- The default format is the standard Wikipedia timestamp. local lang = mw.language.getContentLanguage() local function getDate(format, ts) local success, date = pcall(lang.formatDate, lang, format, ts) if success then return date end end local function getUnixTimestamp(ts) local unixts = getDate('U', ts) if unixts then return tonumber(unixts) end end local t1 = args[1] local t2 = args[2] -- Find the start timestamp and the end timestamp. local startTimestamp, endTimestamp if not t1 then -- Find the first and last second in the current year. local currentYear = tonumber(getDate('Y')) local currentYearStartUnix = tonumber(getUnixTimestamp('1 Jan ' .. tostring(currentYear))) local currentYearEndUnix = tonumber(getUnixTimestamp('1 Jan ' .. tostring(currentYear + 1))) - 1 startTimestamp = '@' .. tostring(currentYearStartUnix) -- @ is used to denote Unix timestamps with lang:formatDate. endTimestamp = '@' .. tostring(currentYearEndUnix) elseif t1 and not t2 then startTimestamp = '@0' -- the Unix epoch, 1 January 1970 endTimestamp = t1 elseif t1 and t2 then startTimestamp = t1 endTimestamp = t2 end -- Get Unix timestamps and return errors for bad input (or for bugs in the underlying PHP library, of which there are unfortunately a few) local startTimestampUnix = getUnixTimestamp(startTimestamp) local endTimestampUnix = getUnixTimestamp(endTimestamp) if not startTimestampUnix then return raiseError('"' .. tostring(startTimestamp) .. '" was not recognised as a valid timestamp') elseif not endTimestampUnix then return raiseError('"' .. tostring(endTimestamp) .. '" was not recognised as a valid timestamp') elseif startTimestampUnix > endTimestampUnix then return raiseError('the start date must not be later than the end date (start date: "' .. startTimestamp .. '", end date: "' .. endTimestamp .. '")') end -- Get a random number between the two Unix timestamps and return it using the specified format. local randomTimestamp = getBigRandom(startTimestampUnix, endTimestampUnix) local dateFormat = args.format or 'H:i, d F Y (T)' local result = getDate(dateFormat, '@' .. tostring(randomTimestamp)) if result then return result else return raiseError('"' .. dateFormat .. '" is not a valid date format') end end -------------------------------------------------------------------------------------- -- List functions -------------------------------------------------------------------------------------- local function randomizeArray(t, limit) -- Randomizes an array. It works by iterating through the list backwards, each time swapping the entry -- "i" with a random entry. Courtesy of Xinhuan at http://forums.wowace.com/showthread.php?p=279756 -- If the limit parameter is set, the array is shortened to that many elements after being randomized. -- The lowest possible value is 0, and the highest possible is the length of the array. local len = #t for i = len, 2, -1 do local r = math.random(i) t[i], t[r] = t[r], t[i] end if limit and limit < len then local ret = {} for i, v in ipairs(t) do if i > limit then break end ret[i] = v end return ret else return t end end local function removeBlanks(t) -- Removes blank entries from an array so that it can be used with ipairs. local ret = {} for k, v in pairs(t) do if type(k) == 'number' then table.insert(ret, k) end end table.sort(ret) for i, v in ipairs(ret) do ret[i] = t[v] end return ret end local function makeSeparator(sep) if sep == 'space' then -- Include an easy way to use spaces as separators. return ' ' elseif sep == 'newline' then -- Ditto for newlines return '\n' elseif type(sep) == 'string' then -- If the separator is a recognised MediaWiki separator, use that. Otherwise use the value of sep if it is a string. local mwseparators = {'dot', 'pipe', 'comma', 'tpt-languages'} for _, mwsep in ipairs(mwseparators) do if sep == mwsep then return mw.message.new( sep .. '-separator' ):plain() end end return sep end end local function makeRandomList(args) local list = removeBlanks(args) list = randomizeArray(list, tonumber(args.limit)) return list end function l.item(args) -- Returns a random item from a numbered list. local list = removeBlanks(args) local len = #list if len >= 1 then return list[math.random(len)] end end function l.list(args) -- Randomizes a list and concatenates the result with a separator. local list = makeRandomList(args) local sep = makeSeparator(args.sep or args.separator) return table.concat(list, sep) end function l.text_list(args) -- Randomizes a list and concatenates the result, text-style. Accepts separator and conjunction arguments. local list = makeRandomList(args) local sep = makeSeparator(args.sep or args.separator) local conj = makeSeparator(args.conj or args.conjunction) return mw.text.listToText(list, sep, conj) end function l.array(args) -- Returns a Lua array, randomized. For use from other Lua modules. return randomizeArray(args.t, args.limit) end -------------------------------------------------------------------------------------- -- HTML list function -------------------------------------------------------------------------------------- function l.html_list(args, listType) -- Randomizes a list and turns it into an HTML list. Uses [[Module:List]]. listType = listType or 'bulleted' local listArgs = makeRandomList(args) -- Arguments for [[Module:List]]. for k, v in pairs(args) do if type(k) == 'string' then listArgs[k] = v end end return makeList(listType, listArgs) end -------------------------------------------------------------------------------------- -- The main function. Called from other Lua modules. -------------------------------------------------------------------------------------- function p.main(funcName, args, listType) -- Sets the seed for the random number generator and passes control over to the other functions. local same = yesno(args.same) if not same then -- Generates a different number every time the module is called, even from the same page. -- This is because of the variability of os.clock (the time in seconds that the Lua script has been running for). math.randomseed(mw.site.stats.edits + mw.site.stats.pages + os.time() + math.floor(os.clock() * 1000000000)) else if not cfg.lowTraffic then -- Make the seed as random as possible without using anything time-based. This means that the same random number -- will be generated for the same input from the same page - necessary behaviour for some wikicode templates that -- assume bad pseudo-random-number generation. local stats = mw.site.stats local views = stats.views or 0 -- This is not always available, so we need a backup. local seed = views + stats.pages + stats.articles + stats.files + stats.edits + stats.users + stats.activeUsers + stats.admins -- Make this as random as possible without using os.time() or os.clock() math.randomseed(seed) else -- Make the random seed change every n seconds, where n is set by cfg.seedRefreshRate. -- This is useful for low-traffic wikis where new edits may not happen very often. math.randomseed(math.floor(os.time() / cfg.seedRefreshRate)) end end if type(args) ~= 'table' then error('the second argument to p.main must be a table') end return l[funcName](args, listType) end -------------------------------------------------------------------------------------- -- Process arguments from #invoke -------------------------------------------------------------------------------------- local function makeWrapper(funcName, listType) -- This function provides a wrapper for argument-processing from #invoke. -- listType is only used with p.html_list, and is nil the rest of the time. return function (frame) -- If called via #invoke, use the args passed into the invoking template, or the args passed to #invoke if any exist. -- Otherwise assume args are being passed directly in from the debug console or from another Lua module. local origArgs if frame == mw.getCurrentFrame() then origArgs = frame:getParent().args for k, v in pairs(frame.args) do origArgs = frame.args break end else origArgs = frame end -- Trim whitespace and remove blank arguments. local args = {} for k, v in pairs(origArgs) do if type(v) == 'string' then v = mw.text.trim(v) end if v ~= '' then args[k] = v end end return p.main(funcName, args, listType) end end -- Process arguments for HTML list functions. local htmlListFuncs = { bulleted_list = 'bulleted', unbulleted_list = 'unbulleted', horizontal_list = 'horizontal', ordered_list = 'ordered', horizontal_ordered_list = 'horizontal_ordered' } for funcName, listType in pairs(htmlListFuncs) do p[funcName] = makeWrapper('html_list', listType) end -- Process arguments for other functions. local otherFuncs = {'number', 'date', 'item', 'list', 'text_list'} for _, funcName in ipairs(otherFuncs) do p[funcName] = makeWrapper(funcName) end return p ee35eaddf353b9f1503193207f6eade28db3c086 88 87 2023-10-05T13:25:26Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Random]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- This module contains a number of functions that make use of random numbers. local cfg = {} -------------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------------- -- Set this to true if your wiki has a traffic rate of less than one edit every two minutes or so. -- This will prevent the same "random" number being generated many times in a row until a new edit is made -- to the wiki. This setting is only relevant if the |same= parameter is set. cfg.lowTraffic = false -- If cfg.lowTraffic is set to true, and the |same= parameter is set, this value is used for the refresh rate of the random seed. -- This is the number of seconds until the seed is changed. Getting this right is tricky. If you set it too high, the same number -- will be returned many times in a row. If you set it too low, you may get different random numbers appearing on the same page, -- particularly for pages that take many seconds to process. cfg.seedRefreshRate = 60 -------------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------------- local p = {} -- For functions available from other Lua modules. local l = {} -- For functions not available from other Lua modules, but that need to be accessed using table keys. local yesno = require('Module:Yesno') local makeList = require('Module:List').makeList -------------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------------- local function raiseError(msg) -- This helps to generate a wikitext error. It is the calling function's responsibility as to how to include it in the output. return mw.ustring.format('<b class="error">[[Module:Random]] error: %s.</b>', msg) end -------------------------------------------------------------------------------------- -- random number function -------------------------------------------------------------------------------------- local function getBigRandom(l, u) -- Gets a random integer between l and u, and is not limited to RAND_MAX. local r = 0 local n = 2^math.random(30) -- Any power of 2. local limit = math.ceil(53 / (math.log(n) / math.log(2))) for i = 1, limit do r = r + math.random(0, n - 1) / (n^i) end return math.floor(r * (u - l + 1)) + l end function l.number(args) -- Gets a random number. first = tonumber(args[1]) second = tonumber(args[2]) -- This needs to use if statements as math.random won't accept explicit nil values as arguments. if first then if second then if first > second then -- Second number cannot be less than the first, or it causes an error. first, second = second, first end return getBigRandom(first, second) else return getBigRandom(1, first) end else return math.random() end end -------------------------------------------------------------------------------------- -- Date function -------------------------------------------------------------------------------------- function l.date(args) -- This function gets random dates, and takes timestamps as positional arguments. -- With no arguments specified, it outputs a random date in the current year. -- With two arguments specified, it outputs a random date between the timestamps. -- With one argument specified, the date is a random date between the unix epoch (1 Jan 1970) and the timestamp. -- The output can be formatted using the "format" argument, which works in the same way as the #time parser function. -- The default format is the standard Wikipedia timestamp. local lang = mw.language.getContentLanguage() local function getDate(format, ts) local success, date = pcall(lang.formatDate, lang, format, ts) if success then return date end end local function getUnixTimestamp(ts) local unixts = getDate('U', ts) if unixts then return tonumber(unixts) end end local t1 = args[1] local t2 = args[2] -- Find the start timestamp and the end timestamp. local startTimestamp, endTimestamp if not t1 then -- Find the first and last second in the current year. local currentYear = tonumber(getDate('Y')) local currentYearStartUnix = tonumber(getUnixTimestamp('1 Jan ' .. tostring(currentYear))) local currentYearEndUnix = tonumber(getUnixTimestamp('1 Jan ' .. tostring(currentYear + 1))) - 1 startTimestamp = '@' .. tostring(currentYearStartUnix) -- @ is used to denote Unix timestamps with lang:formatDate. endTimestamp = '@' .. tostring(currentYearEndUnix) elseif t1 and not t2 then startTimestamp = '@0' -- the Unix epoch, 1 January 1970 endTimestamp = t1 elseif t1 and t2 then startTimestamp = t1 endTimestamp = t2 end -- Get Unix timestamps and return errors for bad input (or for bugs in the underlying PHP library, of which there are unfortunately a few) local startTimestampUnix = getUnixTimestamp(startTimestamp) local endTimestampUnix = getUnixTimestamp(endTimestamp) if not startTimestampUnix then return raiseError('"' .. tostring(startTimestamp) .. '" was not recognised as a valid timestamp') elseif not endTimestampUnix then return raiseError('"' .. tostring(endTimestamp) .. '" was not recognised as a valid timestamp') elseif startTimestampUnix > endTimestampUnix then return raiseError('the start date must not be later than the end date (start date: "' .. startTimestamp .. '", end date: "' .. endTimestamp .. '")') end -- Get a random number between the two Unix timestamps and return it using the specified format. local randomTimestamp = getBigRandom(startTimestampUnix, endTimestampUnix) local dateFormat = args.format or 'H:i, d F Y (T)' local result = getDate(dateFormat, '@' .. tostring(randomTimestamp)) if result then return result else return raiseError('"' .. dateFormat .. '" is not a valid date format') end end -------------------------------------------------------------------------------------- -- List functions -------------------------------------------------------------------------------------- local function randomizeArray(t, limit) -- Randomizes an array. It works by iterating through the list backwards, each time swapping the entry -- "i" with a random entry. Courtesy of Xinhuan at http://forums.wowace.com/showthread.php?p=279756 -- If the limit parameter is set, the array is shortened to that many elements after being randomized. -- The lowest possible value is 0, and the highest possible is the length of the array. local len = #t for i = len, 2, -1 do local r = math.random(i) t[i], t[r] = t[r], t[i] end if limit and limit < len then local ret = {} for i, v in ipairs(t) do if i > limit then break end ret[i] = v end return ret else return t end end local function removeBlanks(t) -- Removes blank entries from an array so that it can be used with ipairs. local ret = {} for k, v in pairs(t) do if type(k) == 'number' then table.insert(ret, k) end end table.sort(ret) for i, v in ipairs(ret) do ret[i] = t[v] end return ret end local function makeSeparator(sep) if sep == 'space' then -- Include an easy way to use spaces as separators. return ' ' elseif sep == 'newline' then -- Ditto for newlines return '\n' elseif type(sep) == 'string' then -- If the separator is a recognised MediaWiki separator, use that. Otherwise use the value of sep if it is a string. local mwseparators = {'dot', 'pipe', 'comma', 'tpt-languages'} for _, mwsep in ipairs(mwseparators) do if sep == mwsep then return mw.message.new( sep .. '-separator' ):plain() end end return sep end end local function makeRandomList(args) local list = removeBlanks(args) list = randomizeArray(list, tonumber(args.limit)) return list end function l.item(args) -- Returns a random item from a numbered list. local list = removeBlanks(args) local len = #list if len >= 1 then return list[math.random(len)] end end function l.list(args) -- Randomizes a list and concatenates the result with a separator. local list = makeRandomList(args) local sep = makeSeparator(args.sep or args.separator) return table.concat(list, sep) end function l.text_list(args) -- Randomizes a list and concatenates the result, text-style. Accepts separator and conjunction arguments. local list = makeRandomList(args) local sep = makeSeparator(args.sep or args.separator) local conj = makeSeparator(args.conj or args.conjunction) return mw.text.listToText(list, sep, conj) end function l.array(args) -- Returns a Lua array, randomized. For use from other Lua modules. return randomizeArray(args.t, args.limit) end -------------------------------------------------------------------------------------- -- HTML list function -------------------------------------------------------------------------------------- function l.html_list(args, listType) -- Randomizes a list and turns it into an HTML list. Uses [[Module:List]]. listType = listType or 'bulleted' local listArgs = makeRandomList(args) -- Arguments for [[Module:List]]. for k, v in pairs(args) do if type(k) == 'string' then listArgs[k] = v end end return makeList(listType, listArgs) end -------------------------------------------------------------------------------------- -- The main function. Called from other Lua modules. -------------------------------------------------------------------------------------- function p.main(funcName, args, listType) -- Sets the seed for the random number generator and passes control over to the other functions. local same = yesno(args.same) if not same then -- Generates a different number every time the module is called, even from the same page. -- This is because of the variability of os.clock (the time in seconds that the Lua script has been running for). math.randomseed(mw.site.stats.edits + mw.site.stats.pages + os.time() + math.floor(os.clock() * 1000000000)) else if not cfg.lowTraffic then -- Make the seed as random as possible without using anything time-based. This means that the same random number -- will be generated for the same input from the same page - necessary behaviour for some wikicode templates that -- assume bad pseudo-random-number generation. local stats = mw.site.stats local views = stats.views or 0 -- This is not always available, so we need a backup. local seed = views + stats.pages + stats.articles + stats.files + stats.edits + stats.users + stats.activeUsers + stats.admins -- Make this as random as possible without using os.time() or os.clock() math.randomseed(seed) else -- Make the random seed change every n seconds, where n is set by cfg.seedRefreshRate. -- This is useful for low-traffic wikis where new edits may not happen very often. math.randomseed(math.floor(os.time() / cfg.seedRefreshRate)) end end if type(args) ~= 'table' then error('the second argument to p.main must be a table') end return l[funcName](args, listType) end -------------------------------------------------------------------------------------- -- Process arguments from #invoke -------------------------------------------------------------------------------------- local function makeWrapper(funcName, listType) -- This function provides a wrapper for argument-processing from #invoke. -- listType is only used with p.html_list, and is nil the rest of the time. return function (frame) -- If called via #invoke, use the args passed into the invoking template, or the args passed to #invoke if any exist. -- Otherwise assume args are being passed directly in from the debug console or from another Lua module. local origArgs if frame == mw.getCurrentFrame() then origArgs = frame:getParent().args for k, v in pairs(frame.args) do origArgs = frame.args break end else origArgs = frame end -- Trim whitespace and remove blank arguments. local args = {} for k, v in pairs(origArgs) do if type(v) == 'string' then v = mw.text.trim(v) end if v ~= '' then args[k] = v end end return p.main(funcName, args, listType) end end -- Process arguments for HTML list functions. local htmlListFuncs = { bulleted_list = 'bulleted', unbulleted_list = 'unbulleted', horizontal_list = 'horizontal', ordered_list = 'ordered', horizontal_ordered_list = 'horizontal_ordered' } for funcName, listType in pairs(htmlListFuncs) do p[funcName] = makeWrapper('html_list', listType) end -- Process arguments for other functions. local otherFuncs = {'number', 'date', 'item', 'list', 'text_list'} for _, funcName in ipairs(otherFuncs) do p[funcName] = makeWrapper(funcName) end return p ee35eaddf353b9f1503193207f6eade28db3c086 มอดูล:Lua banner 828 53 89 2023-10-05T13:26:57Z PeachFullzZ 2 สร้างหน้าด้วย "-- This module implements the {{lua}} template. local yesno = require('Module:Yesno') local mList = require('Module:List') local mTableTools = require('Module:TableTools') local mMessageBox = require('Module:Message box') local p = {} function p.main(frame) local origArgs = frame:getParent().args local args = {} for k, v in pairs(origArgs) do v = v:match('^%s*(.-)%s*$') if v ~= '' then args[k] = v end end return p._main(args) end fu..." Scribunto text/plain -- This module implements the {{lua}} template. local yesno = require('Module:Yesno') local mList = require('Module:List') local mTableTools = require('Module:TableTools') local mMessageBox = require('Module:Message box') local p = {} function p.main(frame) local origArgs = frame:getParent().args local args = {} for k, v in pairs(origArgs) do v = v:match('^%s*(.-)%s*$') if v ~= '' then args[k] = v end end return p._main(args) end function p._main(args) local modules = mTableTools.compressSparseArray(args) local box = p.renderBox(modules) local trackingCategories = p.renderTrackingCategories(args, modules) return box .. trackingCategories end function p.renderBox(modules) local boxArgs = {} if #modules < 1 then boxArgs.text = '<strong class="error">Error: no modules specified</strong>' else local moduleLinks = {} for i, module in ipairs(modules) do moduleLinks[i] = string.format('[[:%s]]', module) local maybeSandbox = mw.title.new(module .. '/sandbox') if maybeSandbox.exists then moduleLinks[i] = moduleLinks[i] .. string.format(' ([[:%s|sandbox]])', maybeSandbox.fullText) end end local moduleList = mList.makeList('bulleted', moduleLinks) local title = mw.title.getCurrentTitle() if title.subpageText == "doc" then title = title.basePageTitle end if title.contentModel == "Scribunto" then boxArgs.text = 'This module depends on the following other modules:' .. moduleList else boxArgs.text = 'This template uses [[Wikipedia:Lua|Lua]]:\n' .. moduleList end end boxArgs.type = 'notice' boxArgs.small = true boxArgs.image = '[[File:Lua-Logo.svg|30px|alt=|link=]]' return mMessageBox.main('mbox', boxArgs) end function p.renderTrackingCategories(args, modules, titleObj) if yesno(args.nocat) then return '' end local cats = {} -- Error category if #modules < 1 then cats[#cats + 1] = 'Lua templates with errors' end -- Lua templates category titleObj = titleObj or mw.title.getCurrentTitle() local subpageBlacklist = { doc = true, sandbox = true, sandbox2 = true, testcases = true } if not subpageBlacklist[titleObj.subpageText] then local protCatName if titleObj.namespace == 10 then local category = args.category if not category then local categories = { ['Module:String'] = 'Templates based on the String Lua module', ['Module:Math'] = 'Templates based on the Math Lua module', ['Module:BaseConvert'] = 'Templates based on the BaseConvert Lua module', ['Module:Citation/CS1'] = 'Templates based on the Citation/CS1 Lua module' } category = modules[1] and categories[modules[1]] category = category or 'Lua-based templates' end cats[#cats + 1] = category protCatName = "Templates using under-protected Lua modules" elseif titleObj.namespace == 828 then protCatName = "Modules depending on under-protected modules" end if not args.noprotcat and protCatName then local protLevels = { autoconfirmed = 1, extendedconfirmed = 2, templateeditor = 3, sysop = 4 } local currentProt if titleObj.id ~= 0 then -- id is 0 (page does not exist) if am previewing before creating a template. currentProt = titleObj.protectionLevels["edit"][1] end if currentProt == nil then currentProt = 0 else currentProt = protLevels[currentProt] end for i, module in ipairs(modules) do if module ~= "WP:libraryUtil" then local moduleProt = mw.title.new(module).protectionLevels["edit"][1] if moduleProt == nil then moduleProt = 0 else moduleProt = protLevels[moduleProt] end if moduleProt < currentProt then cats[#cats + 1] = protCatName break end end end end end for i, cat in ipairs(cats) do cats[i] = string.format('[[Category:%s]]', cat) end return table.concat(cats) end return p 03ec1b34a40121efc562c0c64a67ebbf57d56dff 90 89 2023-10-05T13:27:22Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Lua banner]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- This module implements the {{lua}} template. local yesno = require('Module:Yesno') local mList = require('Module:List') local mTableTools = require('Module:TableTools') local mMessageBox = require('Module:Message box') local p = {} function p.main(frame) local origArgs = frame:getParent().args local args = {} for k, v in pairs(origArgs) do v = v:match('^%s*(.-)%s*$') if v ~= '' then args[k] = v end end return p._main(args) end function p._main(args) local modules = mTableTools.compressSparseArray(args) local box = p.renderBox(modules) local trackingCategories = p.renderTrackingCategories(args, modules) return box .. trackingCategories end function p.renderBox(modules) local boxArgs = {} if #modules < 1 then boxArgs.text = '<strong class="error">Error: no modules specified</strong>' else local moduleLinks = {} for i, module in ipairs(modules) do moduleLinks[i] = string.format('[[:%s]]', module) local maybeSandbox = mw.title.new(module .. '/sandbox') if maybeSandbox.exists then moduleLinks[i] = moduleLinks[i] .. string.format(' ([[:%s|sandbox]])', maybeSandbox.fullText) end end local moduleList = mList.makeList('bulleted', moduleLinks) local title = mw.title.getCurrentTitle() if title.subpageText == "doc" then title = title.basePageTitle end if title.contentModel == "Scribunto" then boxArgs.text = 'This module depends on the following other modules:' .. moduleList else boxArgs.text = 'This template uses [[Wikipedia:Lua|Lua]]:\n' .. moduleList end end boxArgs.type = 'notice' boxArgs.small = true boxArgs.image = '[[File:Lua-Logo.svg|30px|alt=|link=]]' return mMessageBox.main('mbox', boxArgs) end function p.renderTrackingCategories(args, modules, titleObj) if yesno(args.nocat) then return '' end local cats = {} -- Error category if #modules < 1 then cats[#cats + 1] = 'Lua templates with errors' end -- Lua templates category titleObj = titleObj or mw.title.getCurrentTitle() local subpageBlacklist = { doc = true, sandbox = true, sandbox2 = true, testcases = true } if not subpageBlacklist[titleObj.subpageText] then local protCatName if titleObj.namespace == 10 then local category = args.category if not category then local categories = { ['Module:String'] = 'Templates based on the String Lua module', ['Module:Math'] = 'Templates based on the Math Lua module', ['Module:BaseConvert'] = 'Templates based on the BaseConvert Lua module', ['Module:Citation/CS1'] = 'Templates based on the Citation/CS1 Lua module' } category = modules[1] and categories[modules[1]] category = category or 'Lua-based templates' end cats[#cats + 1] = category protCatName = "Templates using under-protected Lua modules" elseif titleObj.namespace == 828 then protCatName = "Modules depending on under-protected modules" end if not args.noprotcat and protCatName then local protLevels = { autoconfirmed = 1, extendedconfirmed = 2, templateeditor = 3, sysop = 4 } local currentProt if titleObj.id ~= 0 then -- id is 0 (page does not exist) if am previewing before creating a template. currentProt = titleObj.protectionLevels["edit"][1] end if currentProt == nil then currentProt = 0 else currentProt = protLevels[currentProt] end for i, module in ipairs(modules) do if module ~= "WP:libraryUtil" then local moduleProt = mw.title.new(module).protectionLevels["edit"][1] if moduleProt == nil then moduleProt = 0 else moduleProt = protLevels[moduleProt] end if moduleProt < currentProt then cats[#cats + 1] = protCatName break end end end end end for i, cat in ipairs(cats) do cats[i] = string.format('[[Category:%s]]', cat) end return table.concat(cats) end return p 03ec1b34a40121efc562c0c64a67ebbf57d56dff มอดูล:Massage box 828 54 91 2023-10-05T13:28:14Z PeachFullzZ 2 สร้างหน้าด้วย "require('strict') local getArgs local yesno = require('Module:Yesno') local lang = mw.language.getContentLanguage() local CONFIG_MODULE = 'Module:Message box/configuration' local DEMOSPACES = {talk = 'tmbox', image = 'imbox', file = 'imbox', category = 'cmbox', article = 'ambox', main = 'ambox'} -------------------------------------------------------------------------------- -- Helper functions -----------------------------------------------------..." Scribunto text/plain require('strict') local getArgs local yesno = require('Module:Yesno') local lang = mw.language.getContentLanguage() local CONFIG_MODULE = 'Module:Message box/configuration' local DEMOSPACES = {talk = 'tmbox', image = 'imbox', file = 'imbox', category = 'cmbox', article = 'ambox', main = 'ambox'} -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function getTitleObject(...) -- Get the title object, passing the function through pcall -- in case we are over the expensive function count limit. local success, title = pcall(mw.title.new, ...) if success then return title end end local function union(t1, t2) -- Returns the union of two arrays. local vals = {} for i, v in ipairs(t1) do vals[v] = true end for i, v in ipairs(t2) do vals[v] = true end local ret = {} for k in pairs(vals) do table.insert(ret, k) end table.sort(ret) return ret end local function getArgNums(args, prefix) local nums = {} for k, v in pairs(args) do local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end -------------------------------------------------------------------------------- -- Box class definition -------------------------------------------------------------------------------- local MessageBox = {} MessageBox.__index = MessageBox function MessageBox.new(boxType, args, cfg) args = args or {} local obj = {} -- Set the title object and the namespace. obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle() -- Set the config for our box type. obj.cfg = cfg[boxType] if not obj.cfg then local ns = obj.title.namespace -- boxType is "mbox" or invalid input if args.demospace and args.demospace ~= '' then -- implement demospace parameter of mbox local demospace = string.lower(args.demospace) if DEMOSPACES[demospace] then -- use template from DEMOSPACES obj.cfg = cfg[DEMOSPACES[demospace]] elseif string.find( demospace, 'talk' ) then -- demo as a talk page obj.cfg = cfg.tmbox else -- default to ombox obj.cfg = cfg.ombox end elseif ns == 0 then obj.cfg = cfg.ambox -- main namespace elseif ns == 6 then obj.cfg = cfg.imbox -- file namespace elseif ns == 14 then obj.cfg = cfg.cmbox -- category namespace else local nsTable = mw.site.namespaces[ns] if nsTable and nsTable.isTalk then obj.cfg = cfg.tmbox -- any talk namespace else obj.cfg = cfg.ombox -- other namespaces or invalid input end end end -- Set the arguments, and remove all blank arguments except for the ones -- listed in cfg.allowBlankParams. do local newArgs = {} for k, v in pairs(args) do if v ~= '' then newArgs[k] = v end end for i, param in ipairs(obj.cfg.allowBlankParams or {}) do newArgs[param] = args[param] end obj.args = newArgs end -- Define internal data structure. obj.categories = {} obj.classes = {} -- For lazy loading of [[Module:Category handler]]. obj.hasCategories = false return setmetatable(obj, MessageBox) end function MessageBox:addCat(ns, cat, sort) if not cat then return nil end if sort then cat = string.format('[[Category:%s|%s]]', cat, sort) else cat = string.format('[[Category:%s]]', cat) end self.hasCategories = true self.categories[ns] = self.categories[ns] or {} table.insert(self.categories[ns], cat) end function MessageBox:addClass(class) if not class then return nil end table.insert(self.classes, class) end function MessageBox:setParameters() local args = self.args local cfg = self.cfg -- Get type data. self.type = args.type local typeData = cfg.types[self.type] self.invalidTypeError = cfg.showInvalidTypeError and self.type and not typeData typeData = typeData or cfg.types[cfg.default] self.typeClass = typeData.class self.typeImage = typeData.image self.typeImageNeedsLink = typeData.imageNeedsLink -- Find if the box has been wrongly substituted. self.isSubstituted = cfg.substCheck and args.subst == 'SUBST' -- Find whether we are using a small message box. self.isSmall = cfg.allowSmall and ( cfg.smallParam and args.small == cfg.smallParam or not cfg.smallParam and yesno(args.small) ) -- Add attributes, classes and styles. self.id = args.id self.name = args.name if self.name then self:addClass('box-' .. string.gsub(self.name,' ','_')) end if yesno(args.plainlinks) ~= false then self:addClass('plainlinks') end for _, class in ipairs(cfg.classes or {}) do self:addClass(class) end if self.isSmall then self:addClass(cfg.smallClass or 'mbox-small') end self:addClass(self.typeClass) self:addClass(args.class) self.style = args.style self.attrs = args.attrs -- Set text style. self.textstyle = args.textstyle -- Find if we are on the template page or not. This functionality is only -- used if useCollapsibleTextFields is set, or if both cfg.templateCategory -- and cfg.templateCategoryRequireName are set. self.useCollapsibleTextFields = cfg.useCollapsibleTextFields if self.useCollapsibleTextFields or cfg.templateCategory and cfg.templateCategoryRequireName then if self.name then local templateName = mw.ustring.match( self.name, '^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$' ) or self.name templateName = 'Template:' .. templateName self.templateTitle = getTitleObject(templateName) end self.isTemplatePage = self.templateTitle and mw.title.equals(self.title, self.templateTitle) end -- Process data for collapsible text fields. At the moment these are only -- used in {{ambox}}. if self.useCollapsibleTextFields then -- Get the self.issue value. if self.isSmall and args.smalltext then self.issue = args.smalltext else local sect if args.sect == '' then sect = 'This ' .. (cfg.sectionDefault or 'page') elseif type(args.sect) == 'string' then sect = 'This ' .. args.sect end local issue = args.issue issue = type(issue) == 'string' and issue ~= '' and issue or nil local text = args.text text = type(text) == 'string' and text or nil local issues = {} table.insert(issues, sect) table.insert(issues, issue) table.insert(issues, text) self.issue = table.concat(issues, ' ') end -- Get the self.talk value. local talk = args.talk -- Show talk links on the template page or template subpages if the talk -- parameter is blank. if talk == '' and self.templateTitle and ( mw.title.equals(self.templateTitle, self.title) or self.title:isSubpageOf(self.templateTitle) ) then talk = '#' elseif talk == '' then talk = nil end if talk then -- If the talk value is a talk page, make a link to that page. Else -- assume that it's a section heading, and make a link to the talk -- page of the current page with that section heading. local talkTitle = getTitleObject(talk) local talkArgIsTalkPage = true if not talkTitle or not talkTitle.isTalkPage then talkArgIsTalkPage = false talkTitle = getTitleObject( self.title.text, mw.site.namespaces[self.title.namespace].talk.id ) end if talkTitle and talkTitle.exists then local talkText if self.isSmall then local talkLink = talkArgIsTalkPage and talk or (talkTitle.prefixedText .. '#' .. talk) talkText = string.format('([[%s|talk]])', talkLink) else talkText = 'Relevant discussion may be found on' if talkArgIsTalkPage then talkText = string.format( '%s [[%s|%s]].', talkText, talk, talkTitle.prefixedText ) else talkText = string.format( '%s the [[%s#%s|talk page]].', talkText, talkTitle.prefixedText, talk ) end end self.talk = talkText end end -- Get other values. self.fix = args.fix ~= '' and args.fix or nil local date if args.date and args.date ~= '' then date = args.date elseif args.date == '' and self.isTemplatePage then date = lang:formatDate('F Y') end if date then self.date = string.format(" <span class='date-container'><i>(<span class='date'>%s</span>)</i></span>", date) end self.info = args.info if yesno(args.removalnotice) then self.removalNotice = cfg.removalNotice end end -- Set the non-collapsible text field. At the moment this is used by all box -- types other than ambox, and also by ambox when small=yes. if self.isSmall then self.text = args.smalltext or args.text else self.text = args.text end -- Set the below row. self.below = cfg.below and args.below -- General image settings. self.imageCellDiv = not self.isSmall and cfg.imageCellDiv self.imageEmptyCell = cfg.imageEmptyCell -- Left image settings. local imageLeft = self.isSmall and args.smallimage or args.image if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' or not cfg.imageCheckBlank and imageLeft ~= 'none' then self.imageLeft = imageLeft if not imageLeft then local imageSize = self.isSmall and (cfg.imageSmallSize or '30x30px') or '40x40px' self.imageLeft = string.format('[[File:%s|%s%s|alt=]]', self.typeImage or 'Information icon4.svg', imageSize, self.typeImageNeedsLink and "" or "|link=" ) end end -- Right image settings. local imageRight = self.isSmall and args.smallimageright or args.imageright if not (cfg.imageRightNone and imageRight == 'none') then self.imageRight = imageRight end -- set templatestyles self.base_templatestyles = cfg.templatestyles self.templatestyles = args.templatestyles end function MessageBox:setMainspaceCategories() local args = self.args local cfg = self.cfg if not cfg.allowMainspaceCategories then return nil end local nums = {} for _, prefix in ipairs{'cat', 'category', 'all'} do args[prefix .. '1'] = args[prefix] nums = union(nums, getArgNums(args, prefix)) end -- The following is roughly equivalent to the old {{Ambox/category}}. local date = args.date date = type(date) == 'string' and date local preposition = 'from' for _, num in ipairs(nums) do local mainCat = args['cat' .. tostring(num)] or args['category' .. tostring(num)] local allCat = args['all' .. tostring(num)] mainCat = type(mainCat) == 'string' and mainCat allCat = type(allCat) == 'string' and allCat if mainCat and date and date ~= '' then local catTitle = string.format('%s %s %s', mainCat, preposition, date) self:addCat(0, catTitle) catTitle = getTitleObject('Category:' .. catTitle) if not catTitle or not catTitle.exists then self:addCat(0, 'Articles with invalid date parameter in template') end elseif mainCat and (not date or date == '') then self:addCat(0, mainCat) end if allCat then self:addCat(0, allCat) end end end function MessageBox:setTemplateCategories() local args = self.args local cfg = self.cfg -- Add template categories. if cfg.templateCategory then if cfg.templateCategoryRequireName then if self.isTemplatePage then self:addCat(10, cfg.templateCategory) end elseif not self.title.isSubpage then self:addCat(10, cfg.templateCategory) end end -- Add template error categories. if cfg.templateErrorCategory then local templateErrorCategory = cfg.templateErrorCategory local templateCat, templateSort if not self.name and not self.title.isSubpage then templateCat = templateErrorCategory elseif self.isTemplatePage then local paramsToCheck = cfg.templateErrorParamsToCheck or {} local count = 0 for i, param in ipairs(paramsToCheck) do if not args[param] then count = count + 1 end end if count > 0 then templateCat = templateErrorCategory templateSort = tostring(count) end if self.categoryNums and #self.categoryNums > 0 then templateCat = templateErrorCategory templateSort = 'C' end end self:addCat(10, templateCat, templateSort) end end function MessageBox:setAllNamespaceCategories() -- Set categories for all namespaces. if self.invalidTypeError then local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText self:addCat('all', 'Wikipedia message box parameter needs fixing', allSort) end if self.isSubstituted then self:addCat('all', 'Pages with incorrectly substituted templates') end end function MessageBox:setCategories() if self.title.namespace == 0 then self:setMainspaceCategories() elseif self.title.namespace == 10 then self:setTemplateCategories() end self:setAllNamespaceCategories() end function MessageBox:renderCategories() if not self.hasCategories then -- No categories added, no need to pass them to Category handler so, -- if it was invoked, it would return the empty string. -- So we shortcut and return the empty string. return "" end -- Convert category tables to strings and pass them through -- [[Module:Category handler]]. return require('Module:Category handler')._main{ main = table.concat(self.categories[0] or {}), template = table.concat(self.categories[10] or {}), all = table.concat(self.categories.all or {}), nocat = self.args.nocat, page = self.args.page } end function MessageBox:export() local root = mw.html.create() -- Add the subst check error. if self.isSubstituted and self.name then root:tag('b') :addClass('error') :wikitext(string.format( 'Template <code>%s[[Template:%s|%s]]%s</code> has been incorrectly substituted.', mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}') )) end local frame = mw.getCurrentFrame() root:wikitext(frame:extensionTag{ name = 'templatestyles', args = { src = self.base_templatestyles }, }) -- Add support for a single custom templatestyles sheet. Undocumented as -- need should be limited and many templates using mbox are substed; we -- don't want to spread templatestyles sheets around to arbitrary places if self.templatestyles then root:wikitext(frame:extensionTag{ name = 'templatestyles', args = { src = self.templatestyles }, }) end -- Create the box table. local boxTable = root:tag('table') boxTable:attr('id', self.id or nil) for i, class in ipairs(self.classes or {}) do boxTable:addClass(class or nil) end boxTable :cssText(self.style or nil) :attr('role', 'presentation') if self.attrs then boxTable:attr(self.attrs) end -- Add the left-hand image. local row = boxTable:tag('tr') if self.imageLeft then local imageLeftCell = row:tag('td'):addClass('mbox-image') if self.imageCellDiv then -- If we are using a div, redefine imageLeftCell so that the image -- is inside it. Divs use style="width: 52px;", which limits the -- image width to 52px. If any images in a div are wider than that, -- they may overlap with the text or cause other display problems. imageLeftCell = imageLeftCell:tag('div'):addClass('mbox-image-div') end imageLeftCell:wikitext(self.imageLeft or nil) elseif self.imageEmptyCell then -- Some message boxes define an empty cell if no image is specified, and -- some don't. The old template code in templates where empty cells are -- specified gives the following hint: "No image. Cell with some width -- or padding necessary for text cell to have 100% width." row:tag('td') :addClass('mbox-empty-cell') end -- Add the text. local textCell = row:tag('td'):addClass('mbox-text') if self.useCollapsibleTextFields then -- The message box uses advanced text parameters that allow things to be -- collapsible. At the moment, only ambox uses this. textCell:cssText(self.textstyle or nil) local textCellDiv = textCell:tag('div') textCellDiv :addClass('mbox-text-span') :wikitext(self.issue or nil) if (self.talk or self.fix) then textCellDiv:tag('span') :addClass('hide-when-compact') :wikitext(self.talk and (' ' .. self.talk) or nil) :wikitext(self.fix and (' ' .. self.fix) or nil) end textCellDiv:wikitext(self.date and (' ' .. self.date) or nil) if self.info and not self.isSmall then textCellDiv :tag('span') :addClass('hide-when-compact') :wikitext(self.info and (' ' .. self.info) or nil) end if self.removalNotice then textCellDiv:tag('span') :addClass('hide-when-compact') :tag('i') :wikitext(string.format(" (%s)", self.removalNotice)) end else -- Default text formatting - anything goes. textCell :cssText(self.textstyle or nil) :wikitext(self.text or nil) end -- Add the right-hand image. if self.imageRight then local imageRightCell = row:tag('td'):addClass('mbox-imageright') if self.imageCellDiv then -- If we are using a div, redefine imageRightCell so that the image -- is inside it. imageRightCell = imageRightCell:tag('div'):addClass('mbox-image-div') end imageRightCell :wikitext(self.imageRight or nil) end -- Add the below row. if self.below then boxTable:tag('tr') :tag('td') :attr('colspan', self.imageRight and '3' or '2') :addClass('mbox-text') :cssText(self.textstyle or nil) :wikitext(self.below or nil) end -- Add error message for invalid type parameters. if self.invalidTypeError then root:tag('div') :addClass('mbox-invalid-type') :wikitext(string.format( 'This message box is using an invalid "type=%s" parameter and needs fixing.', self.type or '' )) end -- Add categories. root:wikitext(self:renderCategories() or nil) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p, mt = {}, {} function p._exportClasses() -- For testing. return { MessageBox = MessageBox } end function p.main(boxType, args, cfgTables) local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE)) box:setParameters() box:setCategories() return box:export() end function mt.__index(t, k) return function (frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return t.main(k, getArgs(frame, {trim = false, removeBlanks = false})) end end return setmetatable(p, mt) f2fb84f7b817d2d88747f57c40902a0d8be8158a 92 91 2023-10-05T13:28:31Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Massage box]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain require('strict') local getArgs local yesno = require('Module:Yesno') local lang = mw.language.getContentLanguage() local CONFIG_MODULE = 'Module:Message box/configuration' local DEMOSPACES = {talk = 'tmbox', image = 'imbox', file = 'imbox', category = 'cmbox', article = 'ambox', main = 'ambox'} -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function getTitleObject(...) -- Get the title object, passing the function through pcall -- in case we are over the expensive function count limit. local success, title = pcall(mw.title.new, ...) if success then return title end end local function union(t1, t2) -- Returns the union of two arrays. local vals = {} for i, v in ipairs(t1) do vals[v] = true end for i, v in ipairs(t2) do vals[v] = true end local ret = {} for k in pairs(vals) do table.insert(ret, k) end table.sort(ret) return ret end local function getArgNums(args, prefix) local nums = {} for k, v in pairs(args) do local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end -------------------------------------------------------------------------------- -- Box class definition -------------------------------------------------------------------------------- local MessageBox = {} MessageBox.__index = MessageBox function MessageBox.new(boxType, args, cfg) args = args or {} local obj = {} -- Set the title object and the namespace. obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle() -- Set the config for our box type. obj.cfg = cfg[boxType] if not obj.cfg then local ns = obj.title.namespace -- boxType is "mbox" or invalid input if args.demospace and args.demospace ~= '' then -- implement demospace parameter of mbox local demospace = string.lower(args.demospace) if DEMOSPACES[demospace] then -- use template from DEMOSPACES obj.cfg = cfg[DEMOSPACES[demospace]] elseif string.find( demospace, 'talk' ) then -- demo as a talk page obj.cfg = cfg.tmbox else -- default to ombox obj.cfg = cfg.ombox end elseif ns == 0 then obj.cfg = cfg.ambox -- main namespace elseif ns == 6 then obj.cfg = cfg.imbox -- file namespace elseif ns == 14 then obj.cfg = cfg.cmbox -- category namespace else local nsTable = mw.site.namespaces[ns] if nsTable and nsTable.isTalk then obj.cfg = cfg.tmbox -- any talk namespace else obj.cfg = cfg.ombox -- other namespaces or invalid input end end end -- Set the arguments, and remove all blank arguments except for the ones -- listed in cfg.allowBlankParams. do local newArgs = {} for k, v in pairs(args) do if v ~= '' then newArgs[k] = v end end for i, param in ipairs(obj.cfg.allowBlankParams or {}) do newArgs[param] = args[param] end obj.args = newArgs end -- Define internal data structure. obj.categories = {} obj.classes = {} -- For lazy loading of [[Module:Category handler]]. obj.hasCategories = false return setmetatable(obj, MessageBox) end function MessageBox:addCat(ns, cat, sort) if not cat then return nil end if sort then cat = string.format('[[Category:%s|%s]]', cat, sort) else cat = string.format('[[Category:%s]]', cat) end self.hasCategories = true self.categories[ns] = self.categories[ns] or {} table.insert(self.categories[ns], cat) end function MessageBox:addClass(class) if not class then return nil end table.insert(self.classes, class) end function MessageBox:setParameters() local args = self.args local cfg = self.cfg -- Get type data. self.type = args.type local typeData = cfg.types[self.type] self.invalidTypeError = cfg.showInvalidTypeError and self.type and not typeData typeData = typeData or cfg.types[cfg.default] self.typeClass = typeData.class self.typeImage = typeData.image self.typeImageNeedsLink = typeData.imageNeedsLink -- Find if the box has been wrongly substituted. self.isSubstituted = cfg.substCheck and args.subst == 'SUBST' -- Find whether we are using a small message box. self.isSmall = cfg.allowSmall and ( cfg.smallParam and args.small == cfg.smallParam or not cfg.smallParam and yesno(args.small) ) -- Add attributes, classes and styles. self.id = args.id self.name = args.name if self.name then self:addClass('box-' .. string.gsub(self.name,' ','_')) end if yesno(args.plainlinks) ~= false then self:addClass('plainlinks') end for _, class in ipairs(cfg.classes or {}) do self:addClass(class) end if self.isSmall then self:addClass(cfg.smallClass or 'mbox-small') end self:addClass(self.typeClass) self:addClass(args.class) self.style = args.style self.attrs = args.attrs -- Set text style. self.textstyle = args.textstyle -- Find if we are on the template page or not. This functionality is only -- used if useCollapsibleTextFields is set, or if both cfg.templateCategory -- and cfg.templateCategoryRequireName are set. self.useCollapsibleTextFields = cfg.useCollapsibleTextFields if self.useCollapsibleTextFields or cfg.templateCategory and cfg.templateCategoryRequireName then if self.name then local templateName = mw.ustring.match( self.name, '^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$' ) or self.name templateName = 'Template:' .. templateName self.templateTitle = getTitleObject(templateName) end self.isTemplatePage = self.templateTitle and mw.title.equals(self.title, self.templateTitle) end -- Process data for collapsible text fields. At the moment these are only -- used in {{ambox}}. if self.useCollapsibleTextFields then -- Get the self.issue value. if self.isSmall and args.smalltext then self.issue = args.smalltext else local sect if args.sect == '' then sect = 'This ' .. (cfg.sectionDefault or 'page') elseif type(args.sect) == 'string' then sect = 'This ' .. args.sect end local issue = args.issue issue = type(issue) == 'string' and issue ~= '' and issue or nil local text = args.text text = type(text) == 'string' and text or nil local issues = {} table.insert(issues, sect) table.insert(issues, issue) table.insert(issues, text) self.issue = table.concat(issues, ' ') end -- Get the self.talk value. local talk = args.talk -- Show talk links on the template page or template subpages if the talk -- parameter is blank. if talk == '' and self.templateTitle and ( mw.title.equals(self.templateTitle, self.title) or self.title:isSubpageOf(self.templateTitle) ) then talk = '#' elseif talk == '' then talk = nil end if talk then -- If the talk value is a talk page, make a link to that page. Else -- assume that it's a section heading, and make a link to the talk -- page of the current page with that section heading. local talkTitle = getTitleObject(talk) local talkArgIsTalkPage = true if not talkTitle or not talkTitle.isTalkPage then talkArgIsTalkPage = false talkTitle = getTitleObject( self.title.text, mw.site.namespaces[self.title.namespace].talk.id ) end if talkTitle and talkTitle.exists then local talkText if self.isSmall then local talkLink = talkArgIsTalkPage and talk or (talkTitle.prefixedText .. '#' .. talk) talkText = string.format('([[%s|talk]])', talkLink) else talkText = 'Relevant discussion may be found on' if talkArgIsTalkPage then talkText = string.format( '%s [[%s|%s]].', talkText, talk, talkTitle.prefixedText ) else talkText = string.format( '%s the [[%s#%s|talk page]].', talkText, talkTitle.prefixedText, talk ) end end self.talk = talkText end end -- Get other values. self.fix = args.fix ~= '' and args.fix or nil local date if args.date and args.date ~= '' then date = args.date elseif args.date == '' and self.isTemplatePage then date = lang:formatDate('F Y') end if date then self.date = string.format(" <span class='date-container'><i>(<span class='date'>%s</span>)</i></span>", date) end self.info = args.info if yesno(args.removalnotice) then self.removalNotice = cfg.removalNotice end end -- Set the non-collapsible text field. At the moment this is used by all box -- types other than ambox, and also by ambox when small=yes. if self.isSmall then self.text = args.smalltext or args.text else self.text = args.text end -- Set the below row. self.below = cfg.below and args.below -- General image settings. self.imageCellDiv = not self.isSmall and cfg.imageCellDiv self.imageEmptyCell = cfg.imageEmptyCell -- Left image settings. local imageLeft = self.isSmall and args.smallimage or args.image if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' or not cfg.imageCheckBlank and imageLeft ~= 'none' then self.imageLeft = imageLeft if not imageLeft then local imageSize = self.isSmall and (cfg.imageSmallSize or '30x30px') or '40x40px' self.imageLeft = string.format('[[File:%s|%s%s|alt=]]', self.typeImage or 'Information icon4.svg', imageSize, self.typeImageNeedsLink and "" or "|link=" ) end end -- Right image settings. local imageRight = self.isSmall and args.smallimageright or args.imageright if not (cfg.imageRightNone and imageRight == 'none') then self.imageRight = imageRight end -- set templatestyles self.base_templatestyles = cfg.templatestyles self.templatestyles = args.templatestyles end function MessageBox:setMainspaceCategories() local args = self.args local cfg = self.cfg if not cfg.allowMainspaceCategories then return nil end local nums = {} for _, prefix in ipairs{'cat', 'category', 'all'} do args[prefix .. '1'] = args[prefix] nums = union(nums, getArgNums(args, prefix)) end -- The following is roughly equivalent to the old {{Ambox/category}}. local date = args.date date = type(date) == 'string' and date local preposition = 'from' for _, num in ipairs(nums) do local mainCat = args['cat' .. tostring(num)] or args['category' .. tostring(num)] local allCat = args['all' .. tostring(num)] mainCat = type(mainCat) == 'string' and mainCat allCat = type(allCat) == 'string' and allCat if mainCat and date and date ~= '' then local catTitle = string.format('%s %s %s', mainCat, preposition, date) self:addCat(0, catTitle) catTitle = getTitleObject('Category:' .. catTitle) if not catTitle or not catTitle.exists then self:addCat(0, 'Articles with invalid date parameter in template') end elseif mainCat and (not date or date == '') then self:addCat(0, mainCat) end if allCat then self:addCat(0, allCat) end end end function MessageBox:setTemplateCategories() local args = self.args local cfg = self.cfg -- Add template categories. if cfg.templateCategory then if cfg.templateCategoryRequireName then if self.isTemplatePage then self:addCat(10, cfg.templateCategory) end elseif not self.title.isSubpage then self:addCat(10, cfg.templateCategory) end end -- Add template error categories. if cfg.templateErrorCategory then local templateErrorCategory = cfg.templateErrorCategory local templateCat, templateSort if not self.name and not self.title.isSubpage then templateCat = templateErrorCategory elseif self.isTemplatePage then local paramsToCheck = cfg.templateErrorParamsToCheck or {} local count = 0 for i, param in ipairs(paramsToCheck) do if not args[param] then count = count + 1 end end if count > 0 then templateCat = templateErrorCategory templateSort = tostring(count) end if self.categoryNums and #self.categoryNums > 0 then templateCat = templateErrorCategory templateSort = 'C' end end self:addCat(10, templateCat, templateSort) end end function MessageBox:setAllNamespaceCategories() -- Set categories for all namespaces. if self.invalidTypeError then local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText self:addCat('all', 'Wikipedia message box parameter needs fixing', allSort) end if self.isSubstituted then self:addCat('all', 'Pages with incorrectly substituted templates') end end function MessageBox:setCategories() if self.title.namespace == 0 then self:setMainspaceCategories() elseif self.title.namespace == 10 then self:setTemplateCategories() end self:setAllNamespaceCategories() end function MessageBox:renderCategories() if not self.hasCategories then -- No categories added, no need to pass them to Category handler so, -- if it was invoked, it would return the empty string. -- So we shortcut and return the empty string. return "" end -- Convert category tables to strings and pass them through -- [[Module:Category handler]]. return require('Module:Category handler')._main{ main = table.concat(self.categories[0] or {}), template = table.concat(self.categories[10] or {}), all = table.concat(self.categories.all or {}), nocat = self.args.nocat, page = self.args.page } end function MessageBox:export() local root = mw.html.create() -- Add the subst check error. if self.isSubstituted and self.name then root:tag('b') :addClass('error') :wikitext(string.format( 'Template <code>%s[[Template:%s|%s]]%s</code> has been incorrectly substituted.', mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}') )) end local frame = mw.getCurrentFrame() root:wikitext(frame:extensionTag{ name = 'templatestyles', args = { src = self.base_templatestyles }, }) -- Add support for a single custom templatestyles sheet. Undocumented as -- need should be limited and many templates using mbox are substed; we -- don't want to spread templatestyles sheets around to arbitrary places if self.templatestyles then root:wikitext(frame:extensionTag{ name = 'templatestyles', args = { src = self.templatestyles }, }) end -- Create the box table. local boxTable = root:tag('table') boxTable:attr('id', self.id or nil) for i, class in ipairs(self.classes or {}) do boxTable:addClass(class or nil) end boxTable :cssText(self.style or nil) :attr('role', 'presentation') if self.attrs then boxTable:attr(self.attrs) end -- Add the left-hand image. local row = boxTable:tag('tr') if self.imageLeft then local imageLeftCell = row:tag('td'):addClass('mbox-image') if self.imageCellDiv then -- If we are using a div, redefine imageLeftCell so that the image -- is inside it. Divs use style="width: 52px;", which limits the -- image width to 52px. If any images in a div are wider than that, -- they may overlap with the text or cause other display problems. imageLeftCell = imageLeftCell:tag('div'):addClass('mbox-image-div') end imageLeftCell:wikitext(self.imageLeft or nil) elseif self.imageEmptyCell then -- Some message boxes define an empty cell if no image is specified, and -- some don't. The old template code in templates where empty cells are -- specified gives the following hint: "No image. Cell with some width -- or padding necessary for text cell to have 100% width." row:tag('td') :addClass('mbox-empty-cell') end -- Add the text. local textCell = row:tag('td'):addClass('mbox-text') if self.useCollapsibleTextFields then -- The message box uses advanced text parameters that allow things to be -- collapsible. At the moment, only ambox uses this. textCell:cssText(self.textstyle or nil) local textCellDiv = textCell:tag('div') textCellDiv :addClass('mbox-text-span') :wikitext(self.issue or nil) if (self.talk or self.fix) then textCellDiv:tag('span') :addClass('hide-when-compact') :wikitext(self.talk and (' ' .. self.talk) or nil) :wikitext(self.fix and (' ' .. self.fix) or nil) end textCellDiv:wikitext(self.date and (' ' .. self.date) or nil) if self.info and not self.isSmall then textCellDiv :tag('span') :addClass('hide-when-compact') :wikitext(self.info and (' ' .. self.info) or nil) end if self.removalNotice then textCellDiv:tag('span') :addClass('hide-when-compact') :tag('i') :wikitext(string.format(" (%s)", self.removalNotice)) end else -- Default text formatting - anything goes. textCell :cssText(self.textstyle or nil) :wikitext(self.text or nil) end -- Add the right-hand image. if self.imageRight then local imageRightCell = row:tag('td'):addClass('mbox-imageright') if self.imageCellDiv then -- If we are using a div, redefine imageRightCell so that the image -- is inside it. imageRightCell = imageRightCell:tag('div'):addClass('mbox-image-div') end imageRightCell :wikitext(self.imageRight or nil) end -- Add the below row. if self.below then boxTable:tag('tr') :tag('td') :attr('colspan', self.imageRight and '3' or '2') :addClass('mbox-text') :cssText(self.textstyle or nil) :wikitext(self.below or nil) end -- Add error message for invalid type parameters. if self.invalidTypeError then root:tag('div') :addClass('mbox-invalid-type') :wikitext(string.format( 'This message box is using an invalid "type=%s" parameter and needs fixing.', self.type or '' )) end -- Add categories. root:wikitext(self:renderCategories() or nil) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p, mt = {}, {} function p._exportClasses() -- For testing. return { MessageBox = MessageBox } end function p.main(boxType, args, cfgTables) local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE)) box:setParameters() box:setCategories() return box:export() end function mt.__index(t, k) return function (frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return t.main(k, getArgs(frame, {trim = false, removeBlanks = false})) end end return setmetatable(p, mt) f2fb84f7b817d2d88747f57c40902a0d8be8158a แม่แบบ:Yesno-no 10 55 93 2023-10-05T13:30:21Z PeachFullzZ 2 สร้างหน้าด้วย "{{safesubst:<noinclude />yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|no}}}|¬={{{¬|no}}}|def={{{def|no}}}}}<noinclude> {{Documentation|Template:Yesno/doc}} <!--Categories go in the doc page referenced above; interwikis go in Wikidata.--> </noinclude>" wikitext text/x-wiki {{safesubst:<noinclude />yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|no}}}|¬={{{¬|no}}}|def={{{def|no}}}}}<noinclude> {{Documentation|Template:Yesno/doc}} <!--Categories go in the doc page referenced above; interwikis go in Wikidata.--> </noinclude> a7418eb0299ee4917469dc7d17a9562c7a4c44fd 94 93 2023-10-05T13:30:59Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Yesno-no]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki {{safesubst:<noinclude />yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|no}}}|¬={{{¬|no}}}|def={{{def|no}}}}}<noinclude> {{Documentation|Template:Yesno/doc}} <!--Categories go in the doc page referenced above; interwikis go in Wikidata.--> </noinclude> a7418eb0299ee4917469dc7d17a9562c7a4c44fd แม่แบบ:Para 10 56 95 2023-10-05T13:31:48Z PeachFullzZ 2 สร้างหน้าด้วย "<code class="tpl-para" style="word-break:break-word;{{SAFESUBST:<noinclude />#if:{{{plain|}}}|border: none; background-color: inherit;}} {{SAFESUBST:<noinclude />#if:{{{plain|}}}{{{mxt|}}}{{{green|}}}{{{!mxt|}}}{{{red|}}}|color: {{SAFESUBST:<noinclude />#if:{{{mxt|}}}{{{green|}}}|#006400|{{SAFESUBST:<noinclude />#if:{{{!mxt|}}}{{{red|}}}|#8B0000|inherit}}}};}} {{SAFESUBST:<noinclude />#if:{{{style|}}}|{{{style}}}}}">&#124;{{SAFESUBST:<noinclude />#i..." wikitext text/x-wiki <code class="tpl-para" style="word-break:break-word;{{SAFESUBST:<noinclude />#if:{{{plain|}}}|border: none; background-color: inherit;}} {{SAFESUBST:<noinclude />#if:{{{plain|}}}{{{mxt|}}}{{{green|}}}{{{!mxt|}}}{{{red|}}}|color: {{SAFESUBST:<noinclude />#if:{{{mxt|}}}{{{green|}}}|#006400|{{SAFESUBST:<noinclude />#if:{{{!mxt|}}}{{{red|}}}|#8B0000|inherit}}}};}} {{SAFESUBST:<noinclude />#if:{{{style|}}}|{{{style}}}}}">&#124;{{SAFESUBST:<noinclude />#if:{{{1|}}}|{{{1}}}&#61;}}{{{2|}}}</code><noinclude> {{Documentation}} <!--Categories and interwikis go near the bottom of the /doc subpage.--> </noinclude> 06006deea2ed5d552aab61b4332321ab749ae7e8 96 95 2023-10-05T13:32:06Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Para]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki <code class="tpl-para" style="word-break:break-word;{{SAFESUBST:<noinclude />#if:{{{plain|}}}|border: none; background-color: inherit;}} {{SAFESUBST:<noinclude />#if:{{{plain|}}}{{{mxt|}}}{{{green|}}}{{{!mxt|}}}{{{red|}}}|color: {{SAFESUBST:<noinclude />#if:{{{mxt|}}}{{{green|}}}|#006400|{{SAFESUBST:<noinclude />#if:{{{!mxt|}}}{{{red|}}}|#8B0000|inherit}}}};}} {{SAFESUBST:<noinclude />#if:{{{style|}}}|{{{style}}}}}">&#124;{{SAFESUBST:<noinclude />#if:{{{1|}}}|{{{1}}}&#61;}}{{{2|}}}</code><noinclude> {{Documentation}} <!--Categories and interwikis go near the bottom of the /doc subpage.--> </noinclude> 06006deea2ed5d552aab61b4332321ab749ae7e8 มอดูล:Transclusion count 828 57 97 2023-10-05T13:35:44Z PeachFullzZ 2 สร้างหน้าด้วย "local p = {} function p.fetch(frame) local template = nil local return_value = nil -- Use demo parameter if it exists, otherswise use current template name local namespace = mw.title.getCurrentTitle().namespace if frame.args["demo"] and frame.args["demo"] ~= "" then template = mw.ustring.gsub(frame.args["demo"],"^[Tt]emplate:","") elseif namespace == 10 then -- Template namespace template = mw.title.getCurrentTitle().text elseif namespa..." Scribunto text/plain local p = {} function p.fetch(frame) local template = nil local return_value = nil -- Use demo parameter if it exists, otherswise use current template name local namespace = mw.title.getCurrentTitle().namespace if frame.args["demo"] and frame.args["demo"] ~= "" then template = mw.ustring.gsub(frame.args["demo"],"^[Tt]emplate:","") elseif namespace == 10 then -- Template namespace template = mw.title.getCurrentTitle().text elseif namespace == 828 then -- Module namespace template = (mw.site.namespaces[828].name .. ":" .. mw.title.getCurrentTitle().text) end -- If in template or module namespace, look up count in /data if template ~= nil then namespace = mw.title.new(template, "Template").namespace if namespace == 10 or namespace == 828 then template = mw.ustring.gsub(template, "/doc$", "") -- strip /doc from end template = mw.ustring.gsub(template, "/sandbox$", "") -- strip /sandbox from end local index = mw.ustring.sub(mw.title.new(template).text,1,1) local status, data = pcall(function () return(mw.loadData('Module:Transclusion_count/data/' .. (mw.ustring.find(index, "%a") and index or "other"))) end) if status then return_value = tonumber(data[mw.ustring.gsub(template, " ", "_")]) end end end -- If database value doesn't exist, use value passed to template if return_value == nil and frame.args[1] ~= nil then local arg1=mw.ustring.match(frame.args[1], '[%d,]+') if arg1 and arg1 ~= '' then return_value = tonumber(frame:callParserFunction('formatnum', arg1, 'R')) end end return return_value end -- Tabulate this data for [[Wikipedia:Database reports/Templates transcluded on the most pages]] function p.tabulate(frame) local list = {} for i = 65, 91 do local data = mw.loadData('Module:Transclusion count/data/' .. ((i == 91) and 'other' or string.char(i))) for name, count in pairs(data) do table.insert(list, {mw.title.new(name, "Template").fullText, count}) end end table.sort(list, function(a, b) return (a[2] == b[2]) and (a[1] < b[1]) or (a[2] > b[2]) end) local lang = mw.getContentLanguage(); for i = 1, #list do list[i] = ('|-\n| %d || [[%s]] || %s\n'):format(i, list[i][1]:gsub('_', ' '), lang:formatNum(list[i][2])) end return table.concat(list) end return p 000ef6bcbf7b66e727870b0c300c4009da300513 98 97 2023-10-05T13:36:04Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Transclusion count]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local p = {} function p.fetch(frame) local template = nil local return_value = nil -- Use demo parameter if it exists, otherswise use current template name local namespace = mw.title.getCurrentTitle().namespace if frame.args["demo"] and frame.args["demo"] ~= "" then template = mw.ustring.gsub(frame.args["demo"],"^[Tt]emplate:","") elseif namespace == 10 then -- Template namespace template = mw.title.getCurrentTitle().text elseif namespace == 828 then -- Module namespace template = (mw.site.namespaces[828].name .. ":" .. mw.title.getCurrentTitle().text) end -- If in template or module namespace, look up count in /data if template ~= nil then namespace = mw.title.new(template, "Template").namespace if namespace == 10 or namespace == 828 then template = mw.ustring.gsub(template, "/doc$", "") -- strip /doc from end template = mw.ustring.gsub(template, "/sandbox$", "") -- strip /sandbox from end local index = mw.ustring.sub(mw.title.new(template).text,1,1) local status, data = pcall(function () return(mw.loadData('Module:Transclusion_count/data/' .. (mw.ustring.find(index, "%a") and index or "other"))) end) if status then return_value = tonumber(data[mw.ustring.gsub(template, " ", "_")]) end end end -- If database value doesn't exist, use value passed to template if return_value == nil and frame.args[1] ~= nil then local arg1=mw.ustring.match(frame.args[1], '[%d,]+') if arg1 and arg1 ~= '' then return_value = tonumber(frame:callParserFunction('formatnum', arg1, 'R')) end end return return_value end -- Tabulate this data for [[Wikipedia:Database reports/Templates transcluded on the most pages]] function p.tabulate(frame) local list = {} for i = 65, 91 do local data = mw.loadData('Module:Transclusion count/data/' .. ((i == 91) and 'other' or string.char(i))) for name, count in pairs(data) do table.insert(list, {mw.title.new(name, "Template").fullText, count}) end end table.sort(list, function(a, b) return (a[2] == b[2]) and (a[1] < b[1]) or (a[2] > b[2]) end) local lang = mw.getContentLanguage(); for i = 1, #list do list[i] = ('|-\n| %d || [[%s]] || %s\n'):format(i, list[i][1]:gsub('_', ' '), lang:formatNum(list[i][2])) end return table.concat(list) end return p 000ef6bcbf7b66e727870b0c300c4009da300513 มอดูล:Transclusion count/data/A 828 58 99 2023-10-05T13:36:59Z PeachFullzZ 2 สร้างหน้าด้วย "return { ["A-Class"] = 5500, ["AARTalk"] = 8900, ["ACArt"] = 5300, ["AFB_game_box_end"] = 2500, ["AFB_game_box_start"] = 2500, ["AFC_comment"] = 14000, ["AFC_submission"] = 24000, ["AFC_submission_category_header"] = 4600, ["AFD_help"] = 108000, ["AFD_help/styles.css"] = 108000, ["AFI/Picture_box/show_picture"] = 3700, ["AFI_film"] = 8100, ["AFL_Car"] = 2600, ["AFL_Col"] = 2500, ["AFL_Ess"] = 2500, ["AFL_Gee"] = 2500, ["AFL_Haw"] = 2400, ["AFL_Mel"]..." Scribunto text/plain return { ["A-Class"] = 5500, ["AARTalk"] = 8900, ["ACArt"] = 5300, ["AFB_game_box_end"] = 2500, ["AFB_game_box_start"] = 2500, ["AFC_comment"] = 14000, ["AFC_submission"] = 24000, ["AFC_submission_category_header"] = 4600, ["AFD_help"] = 108000, ["AFD_help/styles.css"] = 108000, ["AFI/Picture_box/show_picture"] = 3700, ["AFI_film"] = 8100, ["AFL_Car"] = 2600, ["AFL_Col"] = 2500, ["AFL_Ess"] = 2500, ["AFL_Gee"] = 2500, ["AFL_Haw"] = 2400, ["AFL_Mel"] = 2700, ["AFL_NM"] = 2300, ["AFL_Ric"] = 2400, ["AFL_StK"] = 2900, ["AFL_Tables"] = 12000, ["AFL_Year"] = 2500, ["ALG"] = 2500, ["AMARB"] = 4400, ["AML"] = 4500, ["AMQ"] = 4500, ["AM_station_data"] = 4400, ["ARG"] = 6400, ["ASIN"] = 4600, ["ASN"] = 3400, ["ATP"] = 5000, ["AUS"] = 14000, ["AUT"] = 9500, ["AZE"] = 2600, ["A_note"] = 4300, ["A_or_an"] = 29000, ["Aan"] = 48000, ["Abbr"] = 796000, ["Abbreviation"] = 2300, ["Abbrlink"] = 18000, ["Abot"] = 12000, ["About"] = 152000, ["Absolute_page_title"] = 3900, ["Acad"] = 6500, ["Access_icon"] = 2900, ["According_to_whom"] = 4300, ["AchievementTable"] = 10000, ["Active_politician"] = 20000, ["AdSenseSummary"] = 4100, ["Added"] = 2400, ["Adjacent_communities"] = 26000, ["Adjacent_stations"] = 38000, ["Adjacent_stations/styles.css"] = 38000, ["Adjacent_stations_doc"] = 2000, ["Adjstn"] = 2200, ["Admin"] = 14000, ["Administrator_note"] = 6500, ["Adminnote"] = 3500, ["Advert"] = 18000, ["Aet"] = 5200, ["AfC_age_category"] = 3500, ["AfC_comment"] = 14000, ["AfC_date_category"] = 196000, ["AfC_status/age"] = 3600, ["AfC_status/backlog"] = 4100, ["AfC_submission"] = 37000, ["AfC_submission/comments"] = 23000, ["AfC_submission/declined"] = 23000, ["AfC_submission/declinedivbox"] = 23000, ["AfC_submission/draft"] = 16000, ["AfC_submission/helptools"] = 39000, ["AfC_submission/pending"] = 3500, ["AfC_submission/tools"] = 3600, ["AfC_submission_category_header"] = 5700, ["AfC_submission_category_header/day"] = 5500, ["AfC_submission_category_header/td"] = 5500, ["AfC_talk/C_percentage"] = 3300, ["AfC_topic"] = 25000, ["AfD_categories_horizontal_shortnames"] = 4400, ["AfD_count_link"] = 3800, ["Afd-merged-from"] = 8000, ["AfricaProject"] = 28000, ["Africa_topic"] = 6200, ["After_extra_time"] = 5200, ["Age"] = 37000, ["Age_in_days"] = 4400, ["Age_in_years"] = 3700, ["Age_in_years,_months,_weeks_and_days"] = 4100, ["Age_in_years,_months_and_days"] = 17000, ["Age_in_years_and_days"] = 4000, ["Age_in_years_and_days_nts"] = 3100, ["Agree"] = 2100, ["Ahnentafel"] = 8300, ["Ahnentafel/styles.css"] = 8300, ["Air_Force_Historical_Research_Agency"] = 4300, ["Air_force"] = 5900, ["Air_force/core"] = 5900, ["Aircontent"] = 9400, ["Aircraft_specs"] = 12000, ["Aircraft_specs/convert"] = 12000, ["Aircraft_specs/eng"] = 12000, ["Aircraft_specs/length"] = 12000, ["Aircraft_specs/range"] = 12000, ["Aircraft_specs/speed"] = 12000, ["Airport-dest-list"] = 3600, ["Airport_codes"] = 15000, ["Airport_destination_list"] = 4900, ["Aka"] = 2100, ["Al"] = 66000, ["Album"] = 204000, ["Album_chart"] = 29000, ["Album_chart/chartnote"] = 29000, ["Album_cover_fur"] = 53000, ["Album_label_category"] = 2200, ["Album_label_category/core"] = 2200, ["Album_ratings"] = 76000, ["Album_reviews"] = 5600, ["Albums"] = 7600, ["Albums_category"] = 24000, ["Albums_category/core"] = 24000, ["Albums_category/type/default"] = 24000, ["Align"] = 174000, ["Aligned_table"] = 13000, ["AllIrelandByCountyCatNav"] = 3100, ["AllMovie_name"] = 5800, ["AllMovie_title"] = 28000, ["AllMusic"] = 77000, ["Allcaps"] = 9000, ["Allcaps/styles.css"] = 9000, ["Allmovie"] = 4200, ["Allmovie_title"] = 2200, ["Allmusic"] = 17000, ["Allow_wrap"] = 19000, ["Alumni"] = 2400, ["Always_substitute"] = 8400, ["Ambox"] = 1460000, ["Ambox_globe"] = 36000, ["Ambox_globe_current_red"] = 34000, ["American_English"] = 18000, ["American_football_roster/Footer"] = 3200, ["American_football_roster/Header"] = 3200, ["American_football_roster/Player"] = 3200, ["Americanfootballbox"] = 3300, ["Amg_movie"] = 11000, ["Amg_name"] = 3200, ["Anarchism_announcements"] = 3100, ["Anarchism_announcements/shell"] = 3100, ["Anchor"] = 80000, ["Angbr"] = 2100, ["Angle_bracket"] = 3100, ["Anglican_navbox_titlestyle"] = 14000, ["Anglicise_rank"] = 569000, ["Animal_tasks"] = 19000, ["Anime_News_Network"] = 11000, ["Ann"] = 4700, ["Annotated_link"] = 7900, ["Annual_readership"] = 51000, ["Anonblock"] = 33000, ["Antonym_of_(dis)establish"] = 8700, ["Apostrophe"] = 77000, ["ArbCom_Arab-Israeli_editnotice"] = 2200, ["ArbCom_Arab-Israeli_enforcement"] = 3000, ["Arbitration_Committee_candidate/data"] = 76000, ["Archive"] = 155000, ["Archive-nav"] = 5800, ["Archive_bottom"] = 46000, ["Archive_box"] = 18000, ["Archive_list"] = 73000, ["Archive_navigation"] = 7400, ["Archive_top"] = 28000, ["Archive_top/styles.css"] = 28000, ["Archive_top_green"] = 3000, ["Archivebottom"] = 3600, ["Archivebox"] = 2600, ["Archives"] = 50000, ["Archivetop"] = 3600, ["Army"] = 15000, ["Army/core"] = 15000, ["Art_UK_bio"] = 2400, ["Art_UK_bio/plural"] = 2400, ["Article"] = 2900, ["ArticleHistory"] = 29000, ["Article_alerts_box"] = 3600, ["Article_alerts_box/styles.css"] = 3600, ["Article_for_improvement_banner/Picture_box"] = 3700, ["Article_for_improvement_banner/Picture_box/show_picture"] = 3700, ["Article_history"] = 47000, ["Articles_by_Quality"] = 2300, ["Articles_by_Quality/down"] = 2300, ["Articles_by_Quality/total"] = 2400, ["Articles_by_Quality/up"] = 2300, ["As_of"] = 79000, ["Asbox"] = 2390000, ["Asbox/styles.css"] = 2390000, ["Asia_topic"] = 9900, ["Asof"] = 7200, ["Assessed-Class"] = 18000, ["Assignment"] = 6300, ["Assignment_milestones"] = 5600, ["AstDys"] = 2900, ["Asterisk"] = 2200, ["AthAbbr"] = 4600, ["Atnhead"] = 6000, ["Atop"] = 4700, ["Atopg"] = 2600, ["Attached_KML"] = 14000, ["Au"] = 2500, ["AuEduNewbie"] = 2500, ["Audio"] = 27000, ["Audio_sample"] = 2900, ["AustralianFootball"] = 7400, ["Australian_Dictionary_of_Biography"] = 2400, ["Australian_English"] = 2800, ["Australian_party_style"] = 6000, ["Australian_politics/name"] = 4200, ["Australian_politics/party_colours"] = 6100, ["Austria_metadata_Wikidata"] = 2100, ["Austria_population_Wikidata"] = 2100, ["Aut"] = 8200, ["Authority_control"] = 2020000, ["Authority_control_(arts)"] = 16000, ["Auto_link"] = 79000, ["Autobiography"] = 2100, ["Automated_tools"] = 85000, ["Automated_tools/core"] = 85000, ["Automatic_Taxobox"] = 2500, ["Automatic_archive_navigator"] = 133000, ["Automatic_taxobox"] = 75000, ["Aviation_accidents_and_incidents"] = 2300, ["Awaiting_admin"] = 2600, ["Awaitingadmin"] = 2500, ["Award2"] = 2400, ["Awards"] = 2400, ["Awards_table"] = 5600, ["Awards_table/styles.css"] = 5600, ["Ayd"] = 3000, ["Aye"] = 26000, ["Module:A_or_an"] = 29000, ["Module:A_or_an/words"] = 29000, ["Module:About"] = 153000, ["Module:Adjacent_stations"] = 74000, ["Module:Adjacent_stations/Amtrak"] = 2600, ["Module:Adjacent_stations/Indian_Railways"] = 3200, ["Module:Adjacent_stations/JR_East"] = 2200, ["Module:Adjacent_stations/i18n"] = 74000, ["Module:Administrators'_noticeboard_archives"] = 2000, ["Module:AfC_submission_catcheck"] = 376000, ["Module:AfC_topic"] = 25000, ["Module:Age"] = 1190000, ["Module:Ahnentafel"] = 8300, ["Module:Airport_destination_list"] = 4900, ["Module:Aligned_dates_list"] = 2300, ["Module:Aligned_table"] = 13000, ["Module:Anchor"] = 80000, ["Module:Ancient_Egypt_era"] = 2800, ["Module:Ancient_Egypt_era/data"] = 2800, ["Module:Ancient_Egypt_kings"] = 2800, ["Module:Ancient_Egypt_kings/data"] = 2800, ["Module:Ancient_Olympiads"] = 2800, ["Module:Ancient_Olympiads/data"] = 2800, ["Module:Annotated_link"] = 7900, ["Module:Archive_list"] = 75000, ["Module:Arguments"] = 31900000, ["Module:Armenian"] = 2800, ["Module:Article_history"] = 47000, ["Module:Article_history/Category"] = 47000, ["Module:Article_history/config"] = 47000, ["Module:Article_history/styles.css"] = 47000, ["Module:Asbox"] = 2390000, ["Module:Asbox_stubtree"] = 36000, ["Module:Attached_KML"] = 14000, ["Module:Attached_KML/styles.css"] = 14000, ["Module:Australian_place_map"] = 16000, ["Module:Authority_control"] = 2040000, ["Module:Authority_control/auxiliary"] = 575000, ["Module:Authority_control/config"] = 2040000, ["Module:Automated_taxobox"] = 369000, ["Module:Automatic_archive_navigator"] = 133000, ["Module:Automatic_archive_navigator/config"] = 133000, ["Module:Autotaxobox"] = 569000, } a8ee40712bf0669ff0e9be9f1b4924a5abda651e มอดูล:Uses TemplateStyles 828 59 100 2023-10-05T13:41:27Z PeachFullzZ 2 สร้างหน้าด้วย "local yesno = require('Module:Yesno') local mList = require('Module:List') local mTableTools = require('Module:TableTools') local mMessageBox = require('Module:Message box') local TNT = require('Module:TNT') local p = {} local function format(msg, ...) return TNT.format('I18n/Uses TemplateStyles', msg, ...) end local function getConfig() return mw.loadData('Module:Uses TemplateStyles/config') end local function renderBox(tStyles) local boxArg..." Scribunto text/plain local yesno = require('Module:Yesno') local mList = require('Module:List') local mTableTools = require('Module:TableTools') local mMessageBox = require('Module:Message box') local TNT = require('Module:TNT') local p = {} local function format(msg, ...) return TNT.format('I18n/Uses TemplateStyles', msg, ...) end local function getConfig() return mw.loadData('Module:Uses TemplateStyles/config') end local function renderBox(tStyles) local boxArgs = { type = 'notice', small = true, image = string.format('[[File:Farm-Fresh css add.svg|32px|alt=%s]]', format('logo-alt')) } if #tStyles < 1 then boxArgs.text = string.format('<strong class="error">%s</strong>', format('error-emptylist')) else local cfg = getConfig() local tStylesLinks = {} for i, ts in ipairs(tStyles) do local link = string.format('[[:%s]]', ts) local sandboxLink = nil local tsTitle = mw.title.new(ts) if tsTitle and cfg['sandbox_title'] then local tsSandboxTitle = mw.title.new(string.format( '%s:%s/%s/%s', tsTitle.nsText, tsTitle.baseText, cfg['sandbox_title'], tsTitle.subpageText)) if tsSandboxTitle and tsSandboxTitle.exists then sandboxLink = format('sandboxlink', link, ':' .. tsSandboxTitle.prefixedText) end end tStylesLinks[i] = sandboxLink or link end local tStylesList = mList.makeList('bulleted', tStylesLinks) boxArgs.text = format( mw.title.getCurrentTitle():inNamespaces(828,829) and 'header-module' or 'header-template') .. '\n' .. tStylesList end return mMessageBox.main('mbox', boxArgs) end local function renderTrackingCategories(args, tStyles, titleObj) if yesno(args.nocat) then return '' end local cfg = getConfig() local cats = {} -- Error category if #tStyles < 1 and cfg['error_category'] then cats[#cats + 1] = cfg['error_category'] end -- TemplateStyles category titleObj = titleObj or mw.title.getCurrentTitle() if (titleObj.namespace == 10 or titleObj.namespace == 828) and not cfg['subpage_blacklist'][titleObj.subpageText] then local category = args.category or cfg['default_category'] if category then cats[#cats + 1] = category end if not yesno(args.noprotcat) and (cfg['protection_conflict_category'] or cfg['padlock_pattern']) then local currentProt = titleObj.protectionLevels["edit"] and titleObj.protectionLevels["edit"][1] or nil local addedLevelCat = false local addedPadlockCat = false for i, ts in ipairs(tStyles) do local tsTitleObj = mw.title.new(ts) local tsProt = tsTitleObj.protectionLevels["edit"] and tsTitleObj.protectionLevels["edit"][1] or nil if cfg['padlock_pattern'] and tsProt and not addedPadlockCat then local content = tsTitleObj:getContent() if not content:find(cfg['padlock_pattern']) then cats[#cats + 1] = cfg['missing_padlock_category'] addedPadlockCat = true end end if cfg['protection_conflict_category'] and currentProt and tsProt ~= currentProt and not addedLevelCat then currentProt = cfg['protection_hierarchy'][currentProt] or 0 tsProt = cfg['protection_hierarchy'][tsProt] or 0 if tsProt < currentProt then addedLevelCat = true cats[#cats + 1] = cfg['protection_conflict_category'] end end end end end for i, cat in ipairs(cats) do cats[i] = string.format('[[Category:%s]]', cat) end return table.concat(cats) end function p._main(args, cfg) local tStyles = mTableTools.compressSparseArray(args) local box = renderBox(tStyles) local trackingCategories = renderTrackingCategories(args, tStyles) return box .. trackingCategories end function p.main(frame) local origArgs = frame:getParent().args local args = {} for k, v in pairs(origArgs) do v = v:match('^%s*(.-)%s*$') if v ~= '' then args[k] = v end end return p._main(args) end return p 71ca57c37849f38e3c5ee30061bdae730963e48e 101 100 2023-10-05T13:41:41Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Uses TemplateStyles]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local yesno = require('Module:Yesno') local mList = require('Module:List') local mTableTools = require('Module:TableTools') local mMessageBox = require('Module:Message box') local TNT = require('Module:TNT') local p = {} local function format(msg, ...) return TNT.format('I18n/Uses TemplateStyles', msg, ...) end local function getConfig() return mw.loadData('Module:Uses TemplateStyles/config') end local function renderBox(tStyles) local boxArgs = { type = 'notice', small = true, image = string.format('[[File:Farm-Fresh css add.svg|32px|alt=%s]]', format('logo-alt')) } if #tStyles < 1 then boxArgs.text = string.format('<strong class="error">%s</strong>', format('error-emptylist')) else local cfg = getConfig() local tStylesLinks = {} for i, ts in ipairs(tStyles) do local link = string.format('[[:%s]]', ts) local sandboxLink = nil local tsTitle = mw.title.new(ts) if tsTitle and cfg['sandbox_title'] then local tsSandboxTitle = mw.title.new(string.format( '%s:%s/%s/%s', tsTitle.nsText, tsTitle.baseText, cfg['sandbox_title'], tsTitle.subpageText)) if tsSandboxTitle and tsSandboxTitle.exists then sandboxLink = format('sandboxlink', link, ':' .. tsSandboxTitle.prefixedText) end end tStylesLinks[i] = sandboxLink or link end local tStylesList = mList.makeList('bulleted', tStylesLinks) boxArgs.text = format( mw.title.getCurrentTitle():inNamespaces(828,829) and 'header-module' or 'header-template') .. '\n' .. tStylesList end return mMessageBox.main('mbox', boxArgs) end local function renderTrackingCategories(args, tStyles, titleObj) if yesno(args.nocat) then return '' end local cfg = getConfig() local cats = {} -- Error category if #tStyles < 1 and cfg['error_category'] then cats[#cats + 1] = cfg['error_category'] end -- TemplateStyles category titleObj = titleObj or mw.title.getCurrentTitle() if (titleObj.namespace == 10 or titleObj.namespace == 828) and not cfg['subpage_blacklist'][titleObj.subpageText] then local category = args.category or cfg['default_category'] if category then cats[#cats + 1] = category end if not yesno(args.noprotcat) and (cfg['protection_conflict_category'] or cfg['padlock_pattern']) then local currentProt = titleObj.protectionLevels["edit"] and titleObj.protectionLevels["edit"][1] or nil local addedLevelCat = false local addedPadlockCat = false for i, ts in ipairs(tStyles) do local tsTitleObj = mw.title.new(ts) local tsProt = tsTitleObj.protectionLevels["edit"] and tsTitleObj.protectionLevels["edit"][1] or nil if cfg['padlock_pattern'] and tsProt and not addedPadlockCat then local content = tsTitleObj:getContent() if not content:find(cfg['padlock_pattern']) then cats[#cats + 1] = cfg['missing_padlock_category'] addedPadlockCat = true end end if cfg['protection_conflict_category'] and currentProt and tsProt ~= currentProt and not addedLevelCat then currentProt = cfg['protection_hierarchy'][currentProt] or 0 tsProt = cfg['protection_hierarchy'][tsProt] or 0 if tsProt < currentProt then addedLevelCat = true cats[#cats + 1] = cfg['protection_conflict_category'] end end end end end for i, cat in ipairs(cats) do cats[i] = string.format('[[Category:%s]]', cat) end return table.concat(cats) end function p._main(args, cfg) local tStyles = mTableTools.compressSparseArray(args) local box = renderBox(tStyles) local trackingCategories = renderTrackingCategories(args, tStyles) return box .. trackingCategories end function p.main(frame) local origArgs = frame:getParent().args local args = {} for k, v in pairs(origArgs) do v = v:match('^%s*(.-)%s*$') if v ~= '' then args[k] = v end end return p._main(args) end return p 71ca57c37849f38e3c5ee30061bdae730963e48e มอดูล:TNT 828 60 102 2023-10-05T13:42:24Z PeachFullzZ 2 สร้างหน้าด้วย "-- -- INTRO: (!!! DO NOT RENAME THIS PAGE !!!) -- This module allows any template or module to be copy/pasted between -- wikis without any translation changes. All translation text is stored -- in the global Data:*.tab pages on Commons, and used everywhere. -- -- SEE: https://www.mediawiki.org/wiki/Multilingual_Templates_and_Modules -- -- ATTENTION: -- Please do NOT rename this module - it has to be identical on all wikis. -- Th..." Scribunto text/plain -- -- INTRO: (!!! DO NOT RENAME THIS PAGE !!!) -- This module allows any template or module to be copy/pasted between -- wikis without any translation changes. All translation text is stored -- in the global Data:*.tab pages on Commons, and used everywhere. -- -- SEE: https://www.mediawiki.org/wiki/Multilingual_Templates_and_Modules -- -- ATTENTION: -- Please do NOT rename this module - it has to be identical on all wikis. -- This code is maintained at https://www.mediawiki.org/wiki/Module:TNT -- Please do not modify it anywhere else, as it may get copied and override your changes. -- Suggestions can be made at https://www.mediawiki.org/wiki/Module_talk:TNT -- -- DESCRIPTION: -- The "msg" function uses a Commons dataset to translate a message -- with a given key (e.g. source-table), plus optional arguments -- to the wiki markup in the current content language. -- Use lang=xx to set language. Example: -- -- {{#invoke:TNT | msg -- | I18n/Template:Graphs.tab <!-- https://commons.wikimedia.org/wiki/Data:I18n/Template:Graphs.tab --> -- | source-table <!-- uses a translation message with id = "source-table" --> -- | param1 }} <!-- optional parameter --> -- -- -- The "doc" function will generate the <templatedata> parameter documentation for templates. -- This way all template parameters can be stored and localized in a single Commons dataset. -- NOTE: "doc" assumes that all documentation is located in Data:Templatedata/* on Commons. -- -- {{#invoke:TNT | doc | Graph:Lines }} -- uses https://commons.wikimedia.org/wiki/Data:Templatedata/Graph:Lines.tab -- if the current page is Template:Graph:Lines/doc -- local p = {} local i18nDataset = 'I18n/Module:TNT.tab' -- Forward declaration of the local functions local sanitizeDataset, loadData, link, formatMessage function p.msg(frame) local dataset, id local params = {} local lang = nil for k, v in pairs(frame.args) do if k == 1 then dataset = mw.text.trim(v) elseif k == 2 then id = mw.text.trim(v) elseif type(k) == 'number' then table.insert(params, mw.text.trim(v)) elseif k == 'lang' and v ~= '_' then lang = mw.text.trim(v) end end return formatMessage(dataset, id, params, lang) end -- Identical to p.msg() above, but used from other lua modules -- Parameters: name of dataset, message key, optional arguments -- Example with 2 params: format('I18n/Module:TNT', 'error_bad_msgkey', 'my-key', 'my-dataset') function p.format(dataset, key, ...) local checkType = require('libraryUtil').checkType checkType('format', 1, dataset, 'string') checkType('format', 2, key, 'string') return formatMessage(dataset, key, {...}) end -- Identical to p.msg() above, but used from other lua modules with the language param -- Parameters: language code, name of dataset, message key, optional arguments -- Example with 2 params: formatInLanguage('es', I18n/Module:TNT', 'error_bad_msgkey', 'my-key', 'my-dataset') function p.formatInLanguage(lang, dataset, key, ...) local checkType = require('libraryUtil').checkType checkType('formatInLanguage', 1, lang, 'string') checkType('formatInLanguage', 2, dataset, 'string') checkType('formatInLanguage', 3, key, 'string') return formatMessage(dataset, key, {...}, lang) end -- Obsolete function that adds a 'c:' prefix to the first param. -- "Sandbox/Sample.tab" -> 'c:Data:Sandbox/Sample.tab' function p.link(frame) return link(frame.args[1]) end function p.doc(frame) local dataset = 'Templatedata/' .. sanitizeDataset(frame.args[1]) return frame:extensionTag('templatedata', p.getTemplateData(dataset)) .. formatMessage(i18nDataset, 'edit_doc', {link(dataset)}) end function p.getTemplateData(dataset) -- TODO: add '_' parameter once lua starts reindexing properly for "all" languages local data = loadData(dataset) local names = {} for _, field in pairs(data.schema.fields) do table.insert(names, field.name) end local params = {} local paramOrder = {} for _, row in pairs(data.data) do local newVal = {} local name = nil for pos, val in pairs(row) do local columnName = names[pos] if columnName == 'name' then name = val else newVal[columnName] = val end end if name then params[name] = newVal table.insert(paramOrder, name) end end -- Work around json encoding treating {"1":{...}} as an [{...}] params['zzz123']='' local json = mw.text.jsonEncode({ params=params, paramOrder=paramOrder, description=data.description }) json = string.gsub(json,'"zzz123":"",?', "") return json end -- Local functions sanitizeDataset = function(dataset) if not dataset then return nil end dataset = mw.text.trim(dataset) if dataset == '' then return nil elseif string.sub(dataset,-4) ~= '.tab' then return dataset .. '.tab' else return dataset end end loadData = function(dataset, lang) dataset = sanitizeDataset(dataset) if not dataset then error(formatMessage(i18nDataset, 'error_no_dataset', {})) end -- Give helpful error to thirdparties who try and copy this module. if not mw.ext or not mw.ext.data or not mw.ext.data.get then error('Missing JsonConfig extension; Cannot load https://commons.wikimedia.org/wiki/Data:' .. dataset) end local data = mw.ext.data.get(dataset, lang) if data == false then if dataset == i18nDataset then -- Prevent cyclical calls error('Missing Commons dataset ' .. i18nDataset) else error(formatMessage(i18nDataset, 'error_bad_dataset', {link(dataset)})) end end return data end -- Given a dataset name, convert it to a title with the 'commons:data:' prefix link = function(dataset) return 'c:Data:' .. mw.text.trim(dataset or '') end formatMessage = function(dataset, key, params, lang) for _, row in pairs(loadData(dataset, lang).data) do local id, msg = unpack(row) if id == key then local result = mw.message.newRawMessage(msg, unpack(params or {})) return result:plain() end end if dataset == i18nDataset then -- Prevent cyclical calls error('Invalid message key "' .. key .. '"') else error(formatMessage(i18nDataset, 'error_bad_msgkey', {key, link(dataset)})) end end return p 9d0d10e54abd232c806dcabccaf03e52858634a1 มอดูล:TNT 828 60 103 102 2023-10-05T13:42:40Z PeachFullzZ 2 ป้องกัน "[[มอดูล:TNT]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- -- INTRO: (!!! DO NOT RENAME THIS PAGE !!!) -- This module allows any template or module to be copy/pasted between -- wikis without any translation changes. All translation text is stored -- in the global Data:*.tab pages on Commons, and used everywhere. -- -- SEE: https://www.mediawiki.org/wiki/Multilingual_Templates_and_Modules -- -- ATTENTION: -- Please do NOT rename this module - it has to be identical on all wikis. -- This code is maintained at https://www.mediawiki.org/wiki/Module:TNT -- Please do not modify it anywhere else, as it may get copied and override your changes. -- Suggestions can be made at https://www.mediawiki.org/wiki/Module_talk:TNT -- -- DESCRIPTION: -- The "msg" function uses a Commons dataset to translate a message -- with a given key (e.g. source-table), plus optional arguments -- to the wiki markup in the current content language. -- Use lang=xx to set language. Example: -- -- {{#invoke:TNT | msg -- | I18n/Template:Graphs.tab <!-- https://commons.wikimedia.org/wiki/Data:I18n/Template:Graphs.tab --> -- | source-table <!-- uses a translation message with id = "source-table" --> -- | param1 }} <!-- optional parameter --> -- -- -- The "doc" function will generate the <templatedata> parameter documentation for templates. -- This way all template parameters can be stored and localized in a single Commons dataset. -- NOTE: "doc" assumes that all documentation is located in Data:Templatedata/* on Commons. -- -- {{#invoke:TNT | doc | Graph:Lines }} -- uses https://commons.wikimedia.org/wiki/Data:Templatedata/Graph:Lines.tab -- if the current page is Template:Graph:Lines/doc -- local p = {} local i18nDataset = 'I18n/Module:TNT.tab' -- Forward declaration of the local functions local sanitizeDataset, loadData, link, formatMessage function p.msg(frame) local dataset, id local params = {} local lang = nil for k, v in pairs(frame.args) do if k == 1 then dataset = mw.text.trim(v) elseif k == 2 then id = mw.text.trim(v) elseif type(k) == 'number' then table.insert(params, mw.text.trim(v)) elseif k == 'lang' and v ~= '_' then lang = mw.text.trim(v) end end return formatMessage(dataset, id, params, lang) end -- Identical to p.msg() above, but used from other lua modules -- Parameters: name of dataset, message key, optional arguments -- Example with 2 params: format('I18n/Module:TNT', 'error_bad_msgkey', 'my-key', 'my-dataset') function p.format(dataset, key, ...) local checkType = require('libraryUtil').checkType checkType('format', 1, dataset, 'string') checkType('format', 2, key, 'string') return formatMessage(dataset, key, {...}) end -- Identical to p.msg() above, but used from other lua modules with the language param -- Parameters: language code, name of dataset, message key, optional arguments -- Example with 2 params: formatInLanguage('es', I18n/Module:TNT', 'error_bad_msgkey', 'my-key', 'my-dataset') function p.formatInLanguage(lang, dataset, key, ...) local checkType = require('libraryUtil').checkType checkType('formatInLanguage', 1, lang, 'string') checkType('formatInLanguage', 2, dataset, 'string') checkType('formatInLanguage', 3, key, 'string') return formatMessage(dataset, key, {...}, lang) end -- Obsolete function that adds a 'c:' prefix to the first param. -- "Sandbox/Sample.tab" -> 'c:Data:Sandbox/Sample.tab' function p.link(frame) return link(frame.args[1]) end function p.doc(frame) local dataset = 'Templatedata/' .. sanitizeDataset(frame.args[1]) return frame:extensionTag('templatedata', p.getTemplateData(dataset)) .. formatMessage(i18nDataset, 'edit_doc', {link(dataset)}) end function p.getTemplateData(dataset) -- TODO: add '_' parameter once lua starts reindexing properly for "all" languages local data = loadData(dataset) local names = {} for _, field in pairs(data.schema.fields) do table.insert(names, field.name) end local params = {} local paramOrder = {} for _, row in pairs(data.data) do local newVal = {} local name = nil for pos, val in pairs(row) do local columnName = names[pos] if columnName == 'name' then name = val else newVal[columnName] = val end end if name then params[name] = newVal table.insert(paramOrder, name) end end -- Work around json encoding treating {"1":{...}} as an [{...}] params['zzz123']='' local json = mw.text.jsonEncode({ params=params, paramOrder=paramOrder, description=data.description }) json = string.gsub(json,'"zzz123":"",?', "") return json end -- Local functions sanitizeDataset = function(dataset) if not dataset then return nil end dataset = mw.text.trim(dataset) if dataset == '' then return nil elseif string.sub(dataset,-4) ~= '.tab' then return dataset .. '.tab' else return dataset end end loadData = function(dataset, lang) dataset = sanitizeDataset(dataset) if not dataset then error(formatMessage(i18nDataset, 'error_no_dataset', {})) end -- Give helpful error to thirdparties who try and copy this module. if not mw.ext or not mw.ext.data or not mw.ext.data.get then error('Missing JsonConfig extension; Cannot load https://commons.wikimedia.org/wiki/Data:' .. dataset) end local data = mw.ext.data.get(dataset, lang) if data == false then if dataset == i18nDataset then -- Prevent cyclical calls error('Missing Commons dataset ' .. i18nDataset) else error(formatMessage(i18nDataset, 'error_bad_dataset', {link(dataset)})) end end return data end -- Given a dataset name, convert it to a title with the 'commons:data:' prefix link = function(dataset) return 'c:Data:' .. mw.text.trim(dataset or '') end formatMessage = function(dataset, key, params, lang) for _, row in pairs(loadData(dataset, lang).data) do local id, msg = unpack(row) if id == key then local result = mw.message.newRawMessage(msg, unpack(params or {})) return result:plain() end end if dataset == i18nDataset then -- Prevent cyclical calls error('Invalid message key "' .. key .. '"') else error(formatMessage(i18nDataset, 'error_bad_msgkey', {key, link(dataset)})) end end return p 9d0d10e54abd232c806dcabccaf03e52858634a1 แม่แบบ:อายุปีและวัน 10 35 104 61 2023-10-05T13:46:56Z PeachFullzZ 2 wikitext text/x-wiki <includeonly>{{{{{♥|safesubst:}}}#invoke:age|age_generic|template=age_yd}}</includeonly><noinclude> {{documentation}} </noinclude> 9fa346aa69bad47ed9ab7f3dd28abbba2e1eda49 แม่แบบ:Age in days 10 46 105 78 2023-10-05T13:47:26Z PeachFullzZ 2 wikitext text/x-wiki <includeonly>{{#invoke:age|age_generic|template=age_days}}</includeonly><noinclude>{{documentation}}</noinclude> bb0bc324535b6a107a358bad957a32da94c55ca8 มอดูล:Date 828 61 106 2023-10-05T13:49:09Z PeachFullzZ 2 สร้างหน้าด้วย "-- Date functions for use by other modules. -- I18N and time zones are not supported. local MINUS = '−' -- Unicode U+2212 MINUS SIGN local floor = math.floor local Date, DateDiff, diffmt -- forward declarations local uniq = { 'unique identifier' } local function is_date(t) -- The system used to make a date read-only means there is no unique -- metatable that is conveniently accessible to check. return type(t) == 'table' and t._id == uniq e..." Scribunto text/plain -- Date functions for use by other modules. -- I18N and time zones are not supported. local MINUS = '−' -- Unicode U+2212 MINUS SIGN local floor = math.floor local Date, DateDiff, diffmt -- forward declarations local uniq = { 'unique identifier' } local function is_date(t) -- The system used to make a date read-only means there is no unique -- metatable that is conveniently accessible to check. return type(t) == 'table' and t._id == uniq end local function is_diff(t) return type(t) == 'table' and getmetatable(t) == diffmt end local function _list_join(list, sep) return table.concat(list, sep) end local function collection() -- Return a table to hold items. return { n = 0, add = function (self, item) self.n = self.n + 1 self[self.n] = item end, join = _list_join, } end local function strip_to_nil(text) -- If text is a string, return its trimmed content, or nil if empty. -- Otherwise return text (convenient when Date fields are provided from -- another module which may pass a string, a number, or another type). if type(text) == 'string' then text = text:match('(%S.-)%s*$') end return text end local function is_leap_year(year, calname) -- Return true if year is a leap year. if calname == 'Julian' then return year % 4 == 0 end return (year % 4 == 0 and year % 100 ~= 0) or year % 400 == 0 end local function days_in_month(year, month, calname) -- Return number of days (1..31) in given month (1..12). if month == 2 and is_leap_year(year, calname) then return 29 end return ({ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 })[month] end local function h_m_s(time) -- Return hour, minute, second extracted from fraction of a day. time = floor(time * 24 * 3600 + 0.5) -- number of seconds local second = time % 60 time = floor(time / 60) return floor(time / 60), time % 60, second end local function hms(date) -- Return fraction of a day from date's time, where (0 <= fraction < 1) -- if the values are valid, but could be anything if outside range. return (date.hour + (date.minute + date.second / 60) / 60) / 24 end local function julian_date(date) -- Return jd, jdz from a Julian or Gregorian calendar date where -- jd = Julian date and its fractional part is zero at noon -- jdz = same, but assume time is 00:00:00 if no time given -- http://www.tondering.dk/claus/cal/julperiod.php#formula -- Testing shows this works for all dates from year -9999 to 9999! -- JDN 0 is the 24-hour period starting at noon UTC on Monday -- 1 January 4713 BC = (-4712, 1, 1) Julian calendar -- 24 November 4714 BC = (-4713, 11, 24) Gregorian calendar local offset local a = floor((14 - date.month)/12) local y = date.year + 4800 - a if date.calendar == 'Julian' then offset = floor(y/4) - 32083 else offset = floor(y/4) - floor(y/100) + floor(y/400) - 32045 end local m = date.month + 12*a - 3 local jd = date.day + floor((153*m + 2)/5) + 365*y + offset if date.hastime then jd = jd + hms(date) - 0.5 return jd, jd end return jd, jd - 0.5 end local function set_date_from_jd(date) -- Set the fields of table date from its Julian date field. -- Return true if date is valid. -- http://www.tondering.dk/claus/cal/julperiod.php#formula -- This handles the proleptic Julian and Gregorian calendars. -- Negative Julian dates are not defined but they work. local calname = date.calendar local low, high -- min/max limits for date ranges −9999-01-01 to 9999-12-31 if calname == 'Gregorian' then low, high = -1930999.5, 5373484.49999 elseif calname == 'Julian' then low, high = -1931076.5, 5373557.49999 else return end local jd = date.jd if not (type(jd) == 'number' and low <= jd and jd <= high) then return end local jdn = floor(jd) if date.hastime then local time = jd - jdn -- 0 <= time < 1 if time >= 0.5 then -- if at or after midnight of next day jdn = jdn + 1 time = time - 0.5 else time = time + 0.5 end date.hour, date.minute, date.second = h_m_s(time) else date.second = 0 date.minute = 0 date.hour = 0 end local b, c if calname == 'Julian' then b = 0 c = jdn + 32082 else -- Gregorian local a = jdn + 32044 b = floor((4*a + 3)/146097) c = a - floor(146097*b/4) end local d = floor((4*c + 3)/1461) local e = c - floor(1461*d/4) local m = floor((5*e + 2)/153) date.day = e - floor((153*m + 2)/5) + 1 date.month = m + 3 - 12*floor(m/10) date.year = 100*b + d - 4800 + floor(m/10) return true end local function fix_numbers(numbers, y, m, d, H, M, S, partial, hastime, calendar) -- Put the result of normalizing the given values in table numbers. -- The result will have valid m, d values if y is valid; caller checks y. -- The logic of PHP mktime is followed where m or d can be zero to mean -- the previous unit, and -1 is the one before that, etc. -- Positive values carry forward. local date if not (1 <= m and m <= 12) then date = Date(y, 1, 1) if not date then return end date = date + ((m - 1) .. 'm') y, m = date.year, date.month end local days_hms if not partial then if hastime and H and M and S then if not (0 <= H and H <= 23 and 0 <= M and M <= 59 and 0 <= S and S <= 59) then days_hms = hms({ hour = H, minute = M, second = S }) end end if days_hms or not (1 <= d and d <= days_in_month(y, m, calendar)) then date = date or Date(y, m, 1) if not date then return end date = date + (d - 1 + (days_hms or 0)) y, m, d = date.year, date.month, date.day if days_hms then H, M, S = date.hour, date.minute, date.second end end end numbers.year = y numbers.month = m numbers.day = d if days_hms then -- Don't set H unless it was valid because a valid H will set hastime. numbers.hour = H numbers.minute = M numbers.second = S end end local function set_date_from_numbers(date, numbers, options) -- Set the fields of table date from numeric values. -- Return true if date is valid. if type(numbers) ~= 'table' then return end local y = numbers.year or date.year local m = numbers.month or date.month local d = numbers.day or date.day local H = numbers.hour local M = numbers.minute or date.minute or 0 local S = numbers.second or date.second or 0 local need_fix if y and m and d then date.partial = nil if not (-9999 <= y and y <= 9999 and 1 <= m and m <= 12 and 1 <= d and d <= days_in_month(y, m, date.calendar)) then if not date.want_fix then return end need_fix = true end elseif y and date.partial then if d or not (-9999 <= y and y <= 9999) then return end if m and not (1 <= m and m <= 12) then if not date.want_fix then return end need_fix = true end else return end if date.partial then H = nil -- ignore any time M = nil S = nil else if H then -- It is not possible to set M or S without also setting H. date.hastime = true else H = 0 end if not (0 <= H and H <= 23 and 0 <= M and M <= 59 and 0 <= S and S <= 59) then if date.want_fix then need_fix = true else return end end end date.want_fix = nil if need_fix then fix_numbers(numbers, y, m, d, H, M, S, date.partial, date.hastime, date.calendar) return set_date_from_numbers(date, numbers, options) end date.year = y -- -9999 to 9999 ('n BC' → year = 1 - n) date.month = m -- 1 to 12 (may be nil if partial) date.day = d -- 1 to 31 (* = nil if partial) date.hour = H -- 0 to 59 (*) date.minute = M -- 0 to 59 (*) date.second = S -- 0 to 59 (*) if type(options) == 'table' then for _, k in ipairs({ 'am', 'era', 'format' }) do if options[k] then date.options[k] = options[k] end end end return true end local function make_option_table(options1, options2) -- If options1 is a string, return a table with its settings, or -- if it is a table, use its settings. -- Missing options are set from table options2 or defaults. -- If a default is used, a flag is set so caller knows the value was not intentionally set. -- Valid option settings are: -- am: 'am', 'a.m.', 'AM', 'A.M.' -- 'pm', 'p.m.', 'PM', 'P.M.' (each has same meaning as corresponding item above) -- era: 'BCMINUS', 'BCNEGATIVE', 'BC', 'B.C.', 'BCE', 'B.C.E.', 'AD', 'A.D.', 'CE', 'C.E.' -- Option am = 'am' does not mean the hour is AM; it means 'am' or 'pm' is used, depending on the hour, -- and am = 'pm' has the same meaning. -- Similarly, era = 'BC' means 'BC' is used if year <= 0. -- BCMINUS displays a MINUS if year < 0 and the display format does not include %{era}. -- BCNEGATIVE is similar but displays a hyphen. local result = { bydefault = {} } if type(options1) == 'table' then result.am = options1.am result.era = options1.era elseif type(options1) == 'string' then -- Example: 'am:AM era:BC' or 'am=AM era=BC'. for item in options1:gmatch('%S+') do local lhs, rhs = item:match('^(%w+)[:=](.+)$') if lhs then result[lhs] = rhs end end end options2 = type(options2) == 'table' and options2 or {} local defaults = { am = 'am', era = 'BC' } for k, v in pairs(defaults) do if not result[k] then if options2[k] then result[k] = options2[k] else result[k] = v result.bydefault[k] = true end end end return result end local ampm_options = { -- lhs = input text accepted as an am/pm option -- rhs = code used internally ['am'] = 'am', ['AM'] = 'AM', ['a.m.'] = 'a.m.', ['A.M.'] = 'A.M.', ['pm'] = 'am', -- same as am ['PM'] = 'AM', ['p.m.'] = 'a.m.', ['P.M.'] = 'A.M.', } local era_text = { -- Text for displaying an era with a positive year (after adjusting -- by replacing year with 1 - year if date.year <= 0). -- options.era = { year<=0 , year>0 } ['BCMINUS'] = { 'BC' , '' , isbc = true, sign = MINUS }, ['BCNEGATIVE'] = { 'BC' , '' , isbc = true, sign = '-' }, ['BC'] = { 'BC' , '' , isbc = true }, ['B.C.'] = { 'B.C.' , '' , isbc = true }, ['BCE'] = { 'BCE' , '' , isbc = true }, ['B.C.E.'] = { 'B.C.E.', '' , isbc = true }, ['AD'] = { 'BC' , 'AD' }, ['A.D.'] = { 'B.C.' , 'A.D.' }, ['CE'] = { 'BCE' , 'CE' }, ['C.E.'] = { 'B.C.E.', 'C.E.' }, } local function get_era_for_year(era, year) return (era_text[era] or era_text['BC'])[year > 0 and 2 or 1] or '' end local function strftime(date, format, options) -- Return date formatted as a string using codes similar to those -- in the C strftime library function. local sformat = string.format local shortcuts = { ['%c'] = '%-I:%M %p %-d %B %-Y %{era}', -- date and time: 2:30 pm 1 April 2016 ['%x'] = '%-d %B %-Y %{era}', -- date: 1 April 2016 ['%X'] = '%-I:%M %p', -- time: 2:30 pm } if shortcuts[format] then format = shortcuts[format] end local codes = { a = { field = 'dayabbr' }, A = { field = 'dayname' }, b = { field = 'monthabbr' }, B = { field = 'monthname' }, u = { fmt = '%d' , field = 'dowiso' }, w = { fmt = '%d' , field = 'dow' }, d = { fmt = '%02d', fmt2 = '%d', field = 'day' }, m = { fmt = '%02d', fmt2 = '%d', field = 'month' }, Y = { fmt = '%04d', fmt2 = '%d', field = 'year' }, H = { fmt = '%02d', fmt2 = '%d', field = 'hour' }, M = { fmt = '%02d', fmt2 = '%d', field = 'minute' }, S = { fmt = '%02d', fmt2 = '%d', field = 'second' }, j = { fmt = '%03d', fmt2 = '%d', field = 'dayofyear' }, I = { fmt = '%02d', fmt2 = '%d', field = 'hour', special = 'hour12' }, p = { field = 'hour', special = 'am' }, } options = make_option_table(options, date.options) local amopt = options.am local eraopt = options.era local function replace_code(spaces, modifier, id) local code = codes[id] if code then local fmt = code.fmt if modifier == '-' and code.fmt2 then fmt = code.fmt2 end local value = date[code.field] if not value then return nil -- an undefined field in a partial date end local special = code.special if special then if special == 'hour12' then value = value % 12 value = value == 0 and 12 or value elseif special == 'am' then local ap = ({ ['a.m.'] = { 'a.m.', 'p.m.' }, ['AM'] = { 'AM', 'PM' }, ['A.M.'] = { 'A.M.', 'P.M.' }, })[ampm_options[amopt]] or { 'am', 'pm' } return (spaces == '' and '' or '&nbsp;') .. (value < 12 and ap[1] or ap[2]) end end if code.field == 'year' then local sign = (era_text[eraopt] or {}).sign if not sign or format:find('%{era}', 1, true) then sign = '' if value <= 0 then value = 1 - value end else if value >= 0 then sign = '' else value = -value end end return spaces .. sign .. sformat(fmt, value) end return spaces .. (fmt and sformat(fmt, value) or value) end end local function replace_property(spaces, id) if id == 'era' then -- Special case so can use local era option. local result = get_era_for_year(eraopt, date.year) if result == '' then return '' end return (spaces == '' and '' or '&nbsp;') .. result end local result = date[id] if type(result) == 'string' then return spaces .. result end if type(result) == 'number' then return spaces .. tostring(result) end if type(result) == 'boolean' then return spaces .. (result and '1' or '0') end -- This occurs if id is an undefined field in a partial date, or is the name of a function. return nil end local PERCENT = '\127PERCENT\127' return (format :gsub('%%%%', PERCENT) :gsub('(%s*)%%{(%w+)}', replace_property) :gsub('(%s*)%%(%-?)(%a)', replace_code) :gsub(PERCENT, '%%') ) end local function _date_text(date, fmt, options) -- Return a formatted string representing the given date. if not is_date(date) then error('date:text: need a date (use "date:text()" with a colon)', 2) end if type(fmt) == 'string' and fmt:match('%S') then if fmt:find('%', 1, true) then return strftime(date, fmt, options) end elseif date.partial then fmt = date.month and 'my' or 'y' else fmt = 'dmy' if date.hastime then fmt = (date.second > 0 and 'hms ' or 'hm ') .. fmt end end local function bad_format() -- For consistency with other format processing, return given format -- (or cleaned format if original was not a string) if invalid. return mw.text.nowiki(fmt) end if date.partial then -- Ignore days in standard formats like 'ymd'. if fmt == 'ym' or fmt == 'ymd' then fmt = date.month and '%Y-%m %{era}' or '%Y %{era}' elseif fmt == 'my' or fmt == 'dmy' or fmt == 'mdy' then fmt = date.month and '%B %-Y %{era}' or '%-Y %{era}' elseif fmt == 'y' then fmt = date.month and '%-Y %{era}' or '%-Y %{era}' else return bad_format() end return strftime(date, fmt, options) end local function hm_fmt() local plain = make_option_table(options, date.options).bydefault.am return plain and '%H:%M' or '%-I:%M %p' end local need_time = date.hastime local t = collection() for item in fmt:gmatch('%S+') do local f if item == 'hm' then f = hm_fmt() need_time = false elseif item == 'hms' then f = '%H:%M:%S' need_time = false elseif item == 'ymd' then f = '%Y-%m-%d %{era}' elseif item == 'mdy' then f = '%B %-d, %-Y %{era}' elseif item == 'dmy' then f = '%-d %B %-Y %{era}' else return bad_format() end t:add(f) end fmt = t:join(' ') if need_time then fmt = hm_fmt() .. ' ' .. fmt end return strftime(date, fmt, options) end local day_info = { -- 0=Sun to 6=Sat [0] = { 'อา', 'วันอาทิตย์' }, { 'จ', 'วันจันทร์' }, { 'อ', 'วันอังคาร' }, { 'พ', 'วันพุธ' }, { 'พฤ', 'วันพฤหัสบดี' }, { 'ศ', 'วันศุกร์' }, { 'ส', 'วันเสาร์' }, } local month_info = { -- 1=Jan to 12=Dec { 'ม.ค.', 'มกราคม' }, { 'ก.พ.', 'กุมภาพันธ์' }, { 'มี.ค.', 'มีนาคม' }, { 'เม.ย.', 'เมษายน' }, { 'พ.ค.', 'พฤษภาคม' }, { 'มิ.ย.', 'มิถุนายน' }, { 'ก.ค.', 'กรกฎาคม' }, { 'ส.ค.', 'สิงหาคม' }, { 'ก.ย.', 'กันยายน' }, { 'ต.ค.', 'ตุลาคม' }, { 'พ.ย.', 'พฤศจิกายน' }, { 'ธ.ค.', 'ธันวาคม' }, } local function name_to_number(text, translate) if type(text) == 'string' then return translate[text:lower()] end end local function day_number(text) return name_to_number(text, { sun = 0, sunday = 0, mon = 1, monday = 1, tue = 2, tuesday = 2, wed = 3, wednesday = 3, thu = 4, thursday = 4, fri = 5, friday = 5, sat = 6, saturday = 6, }) end local function month_number(text) return name_to_number(text, { jan = 1, january = 1, feb = 2, february = 2, mar = 3, march = 3, apr = 4, april = 4, may = 5, jun = 6, june = 6, jul = 7, july = 7, aug = 8, august = 8, sep = 9, september = 9, sept = 9, oct = 10, october = 10, nov = 11, november = 11, dec = 12, december = 12, }) end local function _list_text(list, fmt) -- Return a list of formatted strings from a list of dates. if not type(list) == 'table' then error('date:list:text: need "list:text()" with a colon', 2) end local result = { join = _list_join } for i, date in ipairs(list) do result[i] = date:text(fmt) end return result end local function _date_list(date, spec) -- Return a possibly empty numbered table of dates meeting the specification. -- Dates in the list are in ascending order (oldest date first). -- The spec should be a string of form "<count> <day> <op>" -- where each item is optional and -- count = number of items wanted in list -- day = abbreviation or name such as Mon or Monday -- op = >, >=, <, <= (default is > meaning after date) -- If no count is given, the list is for the specified days in date's month. -- The default day is date's day. -- The spec can also be a positive or negative number: -- -5 is equivalent to '5 <' -- 5 is equivalent to '5' which is '5 >' if not is_date(date) then error('date:list: need a date (use "date:list()" with a colon)', 2) end local list = { text = _list_text } if date.partial then return list end local count, offset, operation local ops = { ['>='] = { before = false, include = true }, ['>'] = { before = false, include = false }, ['<='] = { before = true , include = true }, ['<'] = { before = true , include = false }, } if spec then if type(spec) == 'number' then count = floor(spec + 0.5) if count < 0 then count = -count operation = ops['<'] end elseif type(spec) == 'string' then local num, day, op = spec:match('^%s*(%d*)%s*(%a*)%s*([<>=]*)%s*$') if not num then return list end if num ~= '' then count = tonumber(num) end if day ~= '' then local dow = day_number(day:gsub('[sS]$', '')) -- accept plural days if not dow then return list end offset = dow - date.dow end operation = ops[op] else return list end end offset = offset or 0 operation = operation or ops['>'] local datefrom, dayfirst, daylast if operation.before then if offset > 0 or (offset == 0 and not operation.include) then offset = offset - 7 end if count then if count > 1 then offset = offset - 7*(count - 1) end datefrom = date + offset else daylast = date.day + offset dayfirst = daylast % 7 if dayfirst == 0 then dayfirst = 7 end end else if offset < 0 or (offset == 0 and not operation.include) then offset = offset + 7 end if count then datefrom = date + offset else dayfirst = date.day + offset daylast = date.monthdays end end if not count then if daylast < dayfirst then return list end count = floor((daylast - dayfirst)/7) + 1 datefrom = Date(date, {day = dayfirst}) end for i = 1, count do if not datefrom then break end -- exceeds date limits list[i] = datefrom datefrom = datefrom + 7 end return list end -- A table to get the current date/time (UTC), but only if needed. local current = setmetatable({}, { __index = function (self, key) local d = os.date('!*t') self.year = d.year self.month = d.month self.day = d.day self.hour = d.hour self.minute = d.min self.second = d.sec return rawget(self, key) end }) local function extract_date(newdate, text) -- Parse the date/time in text and return n, o where -- n = table of numbers with date/time fields -- o = table of options for AM/PM or AD/BC or format, if any -- or return nothing if date is known to be invalid. -- Caller determines if the values in n are valid. -- A year must be positive ('1' to '9999'); use 'BC' for BC. -- In a y-m-d string, the year must be four digits to avoid ambiguity -- ('0001' to '9999'). The only way to enter year <= 0 is by specifying -- the date as three numeric parameters like ymd Date(-1, 1, 1). -- Dates of form d/m/y, m/d/y, y/m/d are rejected as potentially ambiguous. local date, options = {}, {} if text:sub(-1) == 'Z' then -- Extract date/time from a Wikidata timestamp. -- The year can be 1 to 16 digits but this module handles 1 to 4 digits only. -- Examples: '+2016-06-21T14:30:00Z', '-0000000180-00-00T00:00:00Z'. local sign, y, m, d, H, M, S = text:match('^([+%-])(%d+)%-(%d%d)%-(%d%d)T(%d%d):(%d%d):(%d%d)Z$') if sign then y = tonumber(y) if sign == '-' and y > 0 then y = -y end if y <= 0 then options.era = 'BCE' end date.year = y m = tonumber(m) d = tonumber(d) H = tonumber(H) M = tonumber(M) S = tonumber(S) if m == 0 then newdate.partial = true return date, options end date.month = m if d == 0 then newdate.partial = true return date, options end date.day = d if H > 0 or M > 0 or S > 0 then date.hour = H date.minute = M date.second = S end return date, options end return end local function extract_ymd(item) -- Called when no day or month has been set. local y, m, d = item:match('^(%d%d%d%d)%-(%w+)%-(%d%d?)$') if y then if date.year then return end if m:match('^%d%d?$') then m = tonumber(m) else m = month_number(m) end if m then date.year = tonumber(y) date.month = m date.day = tonumber(d) return true end end end local function extract_day_or_year(item) -- Called when a day would be valid, or -- when a year would be valid if no year has been set and partial is set. local number, suffix = item:match('^(%d%d?%d?%d?)(.*)$') if number then local n = tonumber(number) if #number <= 2 and n <= 31 then suffix = suffix:lower() if suffix == '' or suffix == 'st' or suffix == 'nd' or suffix == 'rd' or suffix == 'th' then date.day = n return true end elseif suffix == '' and newdate.partial and not date.year then date.year = n return true end end end local function extract_month(item) -- A month must be given as a name or abbreviation; a number could be ambiguous. local m = month_number(item) if m then date.month = m return true end end local function extract_time(item) local h, m, s = item:match('^(%d%d?):(%d%d)(:?%d*)$') if date.hour or not h then return end if s ~= '' then s = s:match('^:(%d%d)$') if not s then return end end date.hour = tonumber(h) date.minute = tonumber(m) date.second = tonumber(s) -- nil if empty string return true end local item_count = 0 local index_time local function set_ampm(item) local H = date.hour if H and not options.am and index_time + 1 == item_count then options.am = ampm_options[item] -- caller checked this is not nil if item:match('^[Aa]') then if not (1 <= H and H <= 12) then return end if H == 12 then date.hour = 0 end else if not (1 <= H and H <= 23) then return end if H <= 11 then date.hour = H + 12 end end return true end end for item in text:gsub(',', ' '):gsub('&nbsp;', ' '):gmatch('%S+') do item_count = item_count + 1 if era_text[item] then -- Era is accepted in peculiar places. if options.era then return end options.era = item elseif ampm_options[item] then if not set_ampm(item) then return end elseif item:find(':', 1, true) then if not extract_time(item) then return end index_time = item_count elseif date.day and date.month then if date.year then return -- should be nothing more so item is invalid end if not item:match('^(%d%d?%d?%d?)$') then return end date.year = tonumber(item) elseif date.day then if not extract_month(item) then return end elseif date.month then if not extract_day_or_year(item) then return end elseif extract_month(item) then options.format = 'mdy' elseif extract_ymd(item) then options.format = 'ymd' elseif extract_day_or_year(item) then if date.day then options.format = 'dmy' end else return end end if not date.year or date.year == 0 then return end local era = era_text[options.era] if era and era.isbc then date.year = 1 - date.year end return date, options end local function autofill(date1, date2) -- Fill any missing month or day in each date using the -- corresponding component from the other date, if present, -- or with 1 if both dates are missing the month or day. -- This gives a good result for calculating the difference -- between two partial dates when no range is wanted. -- Return filled date1, date2 (two full dates). local function filled(a, b) -- Return date a filled, if necessary, with month and/or day from date b. -- The filled day is truncated to fit the number of days in the month. local fillmonth, fillday if not a.month then fillmonth = b.month or 1 end if not a.day then fillday = b.day or 1 end if fillmonth or fillday then -- need to create a new date a = Date(a, { month = fillmonth, day = math.min(fillday or a.day, days_in_month(a.year, fillmonth or a.month, a.calendar)) }) end return a end return filled(date1, date2), filled(date2, date1) end local function date_add_sub(lhs, rhs, is_sub) -- Return a new date from calculating (lhs + rhs) or (lhs - rhs), -- or return nothing if invalid. -- The result is nil if the calculated date exceeds allowable limits. -- Caller ensures that lhs is a date; its properties are copied for the new date. if lhs.partial then -- Adding to a partial is not supported. -- Can subtract a date or partial from a partial, but this is not called for that. return end local function is_prefix(text, word, minlen) local n = #text return (minlen or 1) <= n and n <= #word and text == word:sub(1, n) end local function do_days(n) local forcetime, jd if floor(n) == n then jd = lhs.jd else forcetime = not lhs.hastime jd = lhs.jdz end jd = jd + (is_sub and -n or n) if forcetime then jd = tostring(jd) if not jd:find('.', 1, true) then jd = jd .. '.0' end end return Date(lhs, 'juliandate', jd) end if type(rhs) == 'number' then -- Add/subtract days, including fractional days. return do_days(rhs) end if type(rhs) == 'string' then -- rhs is a single component like '26m' or '26 months' (with optional sign). -- Fractions like '3.25d' are accepted for the units which are handled as days. local sign, numstr, id = rhs:match('^%s*([+-]?)([%d%.]+)%s*(%a+)$') if sign then if sign == '-' then is_sub = not (is_sub and true or false) end local y, m, days local num = tonumber(numstr) if not num then return end id = id:lower() if is_prefix(id, 'years') then y = num m = 0 elseif is_prefix(id, 'months') then y = floor(num / 12) m = num % 12 elseif is_prefix(id, 'weeks') then days = num * 7 elseif is_prefix(id, 'days') then days = num elseif is_prefix(id, 'hours') then days = num / 24 elseif is_prefix(id, 'minutes', 3) then days = num / (24 * 60) elseif is_prefix(id, 'seconds') then days = num / (24 * 3600) else return end if days then return do_days(days) end if numstr:find('.', 1, true) then return end if is_sub then y = -y m = -m end assert(-11 <= m and m <= 11) y = lhs.year + y m = lhs.month + m if m > 12 then y = y + 1 m = m - 12 elseif m < 1 then y = y - 1 m = m + 12 end local d = math.min(lhs.day, days_in_month(y, m, lhs.calendar)) return Date(lhs, y, m, d) end end if is_diff(rhs) then local days = rhs.age_days if (is_sub or false) ~= (rhs.isnegative or false) then days = -days end return lhs + days end end local full_date_only = { dayabbr = true, dayname = true, dow = true, dayofweek = true, dowiso = true, dayofweekiso = true, dayofyear = true, gsd = true, juliandate = true, jd = true, jdz = true, jdnoon = true, } -- Metatable for a date's calculated fields. local datemt = { __index = function (self, key) if rawget(self, 'partial') then if full_date_only[key] then return end if key == 'monthabbr' or key == 'monthdays' or key == 'monthname' then if not self.month then return end end end local value if key == 'dayabbr' then value = day_info[self.dow][1] elseif key == 'dayname' then value = day_info[self.dow][2] elseif key == 'dow' then value = (self.jdnoon + 1) % 7 -- day-of-week 0=Sun to 6=Sat elseif key == 'dayofweek' then value = self.dow elseif key == 'dowiso' then value = (self.jdnoon % 7) + 1 -- ISO day-of-week 1=Mon to 7=Sun elseif key == 'dayofweekiso' then value = self.dowiso elseif key == 'dayofyear' then local first = Date(self.year, 1, 1, self.calendar).jdnoon value = self.jdnoon - first + 1 -- day-of-year 1 to 366 elseif key == 'era' then -- Era text (never a negative sign) from year and options. value = get_era_for_year(self.options.era, self.year) elseif key == 'format' then value = self.options.format or 'dmy' elseif key == 'gsd' then -- GSD = 1 from 00:00:00 to 23:59:59 on 1 January 1 AD Gregorian calendar, -- which is from jd 1721425.5 to 1721426.49999. value = floor(self.jd - 1721424.5) elseif key == 'juliandate' or key == 'jd' or key == 'jdz' then local jd, jdz = julian_date(self) rawset(self, 'juliandate', jd) rawset(self, 'jd', jd) rawset(self, 'jdz', jdz) return key == 'jdz' and jdz or jd elseif key == 'jdnoon' then -- Julian date at noon (an integer) on the calendar day when jd occurs. value = floor(self.jd + 0.5) elseif key == 'isleapyear' then value = is_leap_year(self.year, self.calendar) elseif key == 'monthabbr' then value = month_info[self.month][1] elseif key == 'monthdays' then value = days_in_month(self.year, self.month, self.calendar) elseif key == 'monthname' then value = month_info[self.month][2] end if value ~= nil then rawset(self, key, value) return value end end, } -- Date operators. local function mt_date_add(lhs, rhs) if not is_date(lhs) then lhs, rhs = rhs, lhs -- put date on left (it must be a date for this to have been called) end return date_add_sub(lhs, rhs) end local function mt_date_sub(lhs, rhs) if is_date(lhs) then if is_date(rhs) then return DateDiff(lhs, rhs) end return date_add_sub(lhs, rhs, true) end end local function mt_date_concat(lhs, rhs) return tostring(lhs) .. tostring(rhs) end local function mt_date_tostring(self) return self:text() end local function mt_date_eq(lhs, rhs) -- Return true if dates identify same date/time where, for example, -- Date(-4712, 1, 1, 'Julian') == Date(-4713, 11, 24, 'Gregorian') is true. -- This is called only if lhs and rhs have the same type and the same metamethod. if lhs.partial or rhs.partial then -- One date is partial; the other is a partial or a full date. -- The months may both be nil, but must be the same. return lhs.year == rhs.year and lhs.month == rhs.month and lhs.calendar == rhs.calendar end return lhs.jdz == rhs.jdz end local function mt_date_lt(lhs, rhs) -- Return true if lhs < rhs, for example, -- Date('1 Jan 2016') < Date('06:00 1 Jan 2016') is true. -- This is called only if lhs and rhs have the same type and the same metamethod. if lhs.partial or rhs.partial then -- One date is partial; the other is a partial or a full date. if lhs.calendar ~= rhs.calendar then return lhs.calendar == 'Julian' end if lhs.partial then lhs = lhs.partial.first end if rhs.partial then rhs = rhs.partial.first end end return lhs.jdz < rhs.jdz end --[[ Examples of syntax to construct a date: Date(y, m, d, 'julian') default calendar is 'gregorian' Date(y, m, d, H, M, S, 'julian') Date('juliandate', jd, 'julian') if jd contains "." text output includes H:M:S Date('currentdate') Date('currentdatetime') Date('1 April 1995', 'julian') parse date from text Date('1 April 1995 AD', 'julian') using an era sets a flag to do the same for output Date('04:30:59 1 April 1995', 'julian') Date(date) copy of an existing date Date(date, t) same, updated with y,m,d,H,M,S fields from table t Date(t) date with y,m,d,H,M,S fields from table t ]] function Date(...) -- for forward declaration above -- Return a table holding a date assuming a uniform calendar always applies -- (proleptic Gregorian calendar or proleptic Julian calendar), or -- return nothing if date is invalid. -- A partial date has a valid year, however its month may be nil, and -- its day and time fields are nil. -- Field partial is set to false (if a full date) or a table (if a partial date). local calendars = { julian = 'Julian', gregorian = 'Gregorian' } local newdate = { _id = uniq, calendar = 'Gregorian', -- default is Gregorian calendar hastime = false, -- true if input sets a time hour = 0, -- always set hour/minute/second so don't have to handle nil minute = 0, second = 0, options = {}, list = _date_list, subtract = function (self, rhs, options) return DateDiff(self, rhs, options) end, text = _date_text, } local argtype, datetext, is_copy, jd_number, tnums local numindex = 0 local numfields = { 'year', 'month', 'day', 'hour', 'minute', 'second' } local numbers = {} for _, v in ipairs({...}) do v = strip_to_nil(v) local vlower = type(v) == 'string' and v:lower() or nil if v == nil then -- Ignore empty arguments after stripping so modules can directly pass template parameters. elseif calendars[vlower] then newdate.calendar = calendars[vlower] elseif vlower == 'partial' then newdate.partial = true elseif vlower == 'fix' then newdate.want_fix = true elseif is_date(v) then -- Copy existing date (items can be overridden by other arguments). if is_copy or tnums then return end is_copy = true newdate.calendar = v.calendar newdate.partial = v.partial newdate.hastime = v.hastime newdate.options = v.options newdate.year = v.year newdate.month = v.month newdate.day = v.day newdate.hour = v.hour newdate.minute = v.minute newdate.second = v.second elseif type(v) == 'table' then if tnums then return end tnums = {} local tfields = { year=1, month=1, day=1, hour=2, minute=2, second=2 } for tk, tv in pairs(v) do if tfields[tk] then tnums[tk] = tonumber(tv) end if tfields[tk] == 2 then newdate.hastime = true end end else local num = tonumber(v) if not num and argtype == 'setdate' and numindex == 1 then num = month_number(v) end if num then if not argtype then argtype = 'setdate' end if argtype == 'setdate' and numindex < 6 then numindex = numindex + 1 numbers[numfields[numindex]] = num elseif argtype == 'juliandate' and not jd_number then jd_number = num if type(v) == 'string' then if v:find('.', 1, true) then newdate.hastime = true end elseif num ~= floor(num) then -- The given value was a number. The time will be used -- if the fractional part is nonzero. newdate.hastime = true end else return end elseif argtype then return elseif type(v) == 'string' then if v == 'currentdate' or v == 'currentdatetime' or v == 'juliandate' then argtype = v else argtype = 'datetext' datetext = v end else return end end end if argtype == 'datetext' then if tnums or not set_date_from_numbers(newdate, extract_date(newdate, datetext)) then return end elseif argtype == 'juliandate' then newdate.partial = nil newdate.jd = jd_number if not set_date_from_jd(newdate) then return end elseif argtype == 'currentdate' or argtype == 'currentdatetime' then newdate.partial = nil newdate.year = current.year newdate.month = current.month newdate.day = current.day if argtype == 'currentdatetime' then newdate.hour = current.hour newdate.minute = current.minute newdate.second = current.second newdate.hastime = true end newdate.calendar = 'Gregorian' -- ignore any given calendar name elseif argtype == 'setdate' then if tnums or not set_date_from_numbers(newdate, numbers) then return end elseif not (is_copy or tnums) then return end if tnums then newdate.jd = nil -- force recalculation in case jd was set before changes from tnums if not set_date_from_numbers(newdate, tnums) then return end end if newdate.partial then local year = newdate.year local month = newdate.month local first = Date(year, month or 1, 1, newdate.calendar) month = month or 12 local last = Date(year, month, days_in_month(year, month), newdate.calendar) newdate.partial = { first = first, last = last } else newdate.partial = false -- avoid index lookup end setmetatable(newdate, datemt) local readonly = {} local mt = { __index = newdate, __newindex = function(t, k, v) error('date.' .. tostring(k) .. ' is read-only', 2) end, __add = mt_date_add, __sub = mt_date_sub, __concat = mt_date_concat, __tostring = mt_date_tostring, __eq = mt_date_eq, __lt = mt_date_lt, } return setmetatable(readonly, mt) end local function _diff_age(diff, code, options) -- Return a tuple of integer values from diff as specified by code, except that -- each integer may be a list of two integers for a diff with a partial date, or -- return nil if the code is not supported. -- If want round, the least significant unit is rounded to nearest whole unit. -- For a duration, an extra day is added. local wantround, wantduration, wantrange if type(options) == 'table' then wantround = options.round wantduration = options.duration wantrange = options.range else wantround = options end if not is_diff(diff) then local f = wantduration and 'duration' or 'age' error(f .. ': need a date difference (use "diff:' .. f .. '()" with a colon)', 2) end if diff.partial then -- Ignore wantround, wantduration. local function choose(v) if type(v) == 'table' then if not wantrange or v[1] == v[2] then -- Example: Date('partial', 2005) - Date('partial', 2001) gives -- diff.years = { 3, 4 } to show the range of possible results. -- If do not want a range, choose the second value as more expected. return v[2] end end return v end if code == 'ym' or code == 'ymd' then if not wantrange and diff.iszero then -- This avoids an unexpected result such as -- Date('partial', 2001) - Date('partial', 2001) -- giving diff = { years = 0, months = { 0, 11 } } -- which would be reported as 0 years and 11 months. return 0, 0 end return choose(diff.partial.years), choose(diff.partial.months) end if code == 'y' then return choose(diff.partial.years) end if code == 'm' or code == 'w' or code == 'd' then return choose({ diff.partial.mindiff:age(code), diff.partial.maxdiff:age(code) }) end return nil end local extra_days = wantduration and 1 or 0 if code == 'wd' or code == 'w' or code == 'd' then local offset = wantround and 0.5 or 0 local days = diff.age_days + extra_days if code == 'wd' or code == 'd' then days = floor(days + offset) if code == 'd' then return days end return floor(days/7), days % 7 end return floor(days/7 + offset) end local H, M, S = diff.hours, diff.minutes, diff.seconds if code == 'dh' or code == 'dhm' or code == 'dhms' or code == 'h' or code == 'hm' or code == 'hms' or code == 'M' or code == 's' then local days = floor(diff.age_days + extra_days) local inc_hour if wantround then if code == 'dh' or code == 'h' then if M >= 30 then inc_hour = true end elseif code == 'dhm' or code == 'hm' then if S >= 30 then M = M + 1 if M >= 60 then M = 0 inc_hour = true end end elseif code == 'M' then if S >= 30 then M = M + 1 end else -- Nothing needed because S is an integer. end if inc_hour then H = H + 1 if H >= 24 then H = 0 days = days + 1 end end end if code == 'dh' or code == 'dhm' or code == 'dhms' then if code == 'dh' then return days, H elseif code == 'dhm' then return days, H, M else return days, H, M, S end end local hours = days * 24 + H if code == 'h' then return hours elseif code == 'hm' then return hours, M elseif code == 'M' or code == 's' then M = hours * 60 + M if code == 'M' then return M end return M * 60 + S end return hours, M, S end if wantround then local inc_hour if code == 'ymdh' or code == 'ymwdh' then if M >= 30 then inc_hour = true end elseif code == 'ymdhm' or code == 'ymwdhm' then if S >= 30 then M = M + 1 if M >= 60 then M = 0 inc_hour = true end end elseif code == 'ymd' or code == 'ymwd' or code == 'yd' or code == 'md' then if H >= 12 then extra_days = extra_days + 1 end end if inc_hour then H = H + 1 if H >= 24 then H = 0 extra_days = extra_days + 1 end end end local y, m, d = diff.years, diff.months, diff.days if extra_days > 0 then d = d + extra_days if d > 28 or code == 'yd' then -- Recalculate in case have passed a month. diff = diff.date1 + extra_days - diff.date2 y, m, d = diff.years, diff.months, diff.days end end if code == 'ymd' then return y, m, d elseif code == 'yd' then if y > 0 then -- It is known that diff.date1 > diff.date2. diff = diff.date1 - (diff.date2 + (y .. 'y')) end return y, floor(diff.age_days) elseif code == 'md' then return y * 12 + m, d elseif code == 'ym' or code == 'm' then if wantround then if d >= 16 then m = m + 1 if m >= 12 then m = 0 y = y + 1 end end end if code == 'ym' then return y, m end return y * 12 + m elseif code == 'ymw' then local weeks = floor(d/7) if wantround then local days = d % 7 if days > 3 or (days == 3 and H >= 12) then weeks = weeks + 1 end end return y, m, weeks elseif code == 'ymwd' then return y, m, floor(d/7), d % 7 elseif code == 'ymdh' then return y, m, d, H elseif code == 'ymwdh' then return y, m, floor(d/7), d % 7, H elseif code == 'ymdhm' then return y, m, d, H, M elseif code == 'ymwdhm' then return y, m, floor(d/7), d % 7, H, M end if code == 'y' then if wantround and m >= 6 then y = y + 1 end return y end return nil end local function _diff_duration(diff, code, options) if type(options) ~= 'table' then options = { round = options } end options.duration = true return _diff_age(diff, code, options) end -- Metatable for some operations on date differences. diffmt = { -- for forward declaration above __concat = function (lhs, rhs) return tostring(lhs) .. tostring(rhs) end, __tostring = function (self) return tostring(self.age_days) end, __index = function (self, key) local value if key == 'age_days' then if rawget(self, 'partial') then local function jdz(date) return (date.partial and date.partial.first or date).jdz end value = jdz(self.date1) - jdz(self.date2) else value = self.date1.jdz - self.date2.jdz end end if value ~= nil then rawset(self, key, value) return value end end, } function DateDiff(date1, date2, options) -- for forward declaration above -- Return a table with the difference between two dates (date1 - date2). -- The difference is negative if date1 is older than date2. -- Return nothing if invalid. -- If d = date1 - date2 then -- date1 = date2 + d -- If date1 >= date2 and the dates have no H:M:S time specified then -- date1 = date2 + (d.years..'y') + (d.months..'m') + d.days -- where the larger time units are added first. -- The result of Date(2015,1,x) + '1m' is Date(2015,2,28) for -- x = 28, 29, 30, 31. That means, for example, -- d = Date(2015,3,3) - Date(2015,1,31) -- gives d.years, d.months, d.days = 0, 1, 3 (excluding date1). if not (is_date(date1) and is_date(date2) and date1.calendar == date2.calendar) then return end local wantfill if type(options) == 'table' then wantfill = options.fill end local isnegative = false local iszero = false if date1 < date2 then isnegative = true date1, date2 = date2, date1 elseif date1 == date2 then iszero = true end -- It is known that date1 >= date2 (period is from date2 to date1). if date1.partial or date2.partial then -- Two partial dates might have timelines: ---------------------A=================B--- date1 is from A to B inclusive --------C=======D-------------------------- date2 is from C to D inclusive -- date1 > date2 iff A > C (date1.partial.first > date2.partial.first) -- The periods can overlap ('April 2001' - '2001'): -------------A===B------------------------- A=2001-04-01 B=2001-04-30 --------C=====================D------------ C=2001-01-01 D=2001-12-31 if wantfill then date1, date2 = autofill(date1, date2) else local function zdiff(date1, date2) local diff = date1 - date2 if diff.isnegative then return date1 - date1 -- a valid diff in case we call its methods end return diff end local function getdate(date, which) return date.partial and date.partial[which] or date end local maxdiff = zdiff(getdate(date1, 'last'), getdate(date2, 'first')) local mindiff = zdiff(getdate(date1, 'first'), getdate(date2, 'last')) local years, months if maxdiff.years == mindiff.years then years = maxdiff.years if maxdiff.months == mindiff.months then months = maxdiff.months else months = { mindiff.months, maxdiff.months } end else years = { mindiff.years, maxdiff.years } end return setmetatable({ date1 = date1, date2 = date2, partial = { years = years, months = months, maxdiff = maxdiff, mindiff = mindiff, }, isnegative = isnegative, iszero = iszero, age = _diff_age, duration = _diff_duration, }, diffmt) end end local y1, m1 = date1.year, date1.month local y2, m2 = date2.year, date2.month local years = y1 - y2 local months = m1 - m2 local d1 = date1.day + hms(date1) local d2 = date2.day + hms(date2) local days, time if d1 >= d2 then days = d1 - d2 else months = months - 1 -- Get days in previous month (before the "to" date) given December has 31 days. local dpm = m1 > 1 and days_in_month(y1, m1 - 1, date1.calendar) or 31 if d2 >= dpm then days = d1 - hms(date2) else days = dpm - d2 + d1 end end if months < 0 then years = years - 1 months = months + 12 end days, time = math.modf(days) local H, M, S = h_m_s(time) return setmetatable({ date1 = date1, date2 = date2, partial = false, -- avoid index lookup years = years, months = months, days = days, hours = H, minutes = M, seconds = S, isnegative = isnegative, iszero = iszero, age = _diff_age, duration = _diff_duration, }, diffmt) end return { _current = current, _Date = Date, _days_in_month = days_in_month, } 78ea3faee09a817215e1595430285da8cbcf4db9 107 106 2023-10-05T13:49:53Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Date]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- Date functions for use by other modules. -- I18N and time zones are not supported. local MINUS = '−' -- Unicode U+2212 MINUS SIGN local floor = math.floor local Date, DateDiff, diffmt -- forward declarations local uniq = { 'unique identifier' } local function is_date(t) -- The system used to make a date read-only means there is no unique -- metatable that is conveniently accessible to check. return type(t) == 'table' and t._id == uniq end local function is_diff(t) return type(t) == 'table' and getmetatable(t) == diffmt end local function _list_join(list, sep) return table.concat(list, sep) end local function collection() -- Return a table to hold items. return { n = 0, add = function (self, item) self.n = self.n + 1 self[self.n] = item end, join = _list_join, } end local function strip_to_nil(text) -- If text is a string, return its trimmed content, or nil if empty. -- Otherwise return text (convenient when Date fields are provided from -- another module which may pass a string, a number, or another type). if type(text) == 'string' then text = text:match('(%S.-)%s*$') end return text end local function is_leap_year(year, calname) -- Return true if year is a leap year. if calname == 'Julian' then return year % 4 == 0 end return (year % 4 == 0 and year % 100 ~= 0) or year % 400 == 0 end local function days_in_month(year, month, calname) -- Return number of days (1..31) in given month (1..12). if month == 2 and is_leap_year(year, calname) then return 29 end return ({ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 })[month] end local function h_m_s(time) -- Return hour, minute, second extracted from fraction of a day. time = floor(time * 24 * 3600 + 0.5) -- number of seconds local second = time % 60 time = floor(time / 60) return floor(time / 60), time % 60, second end local function hms(date) -- Return fraction of a day from date's time, where (0 <= fraction < 1) -- if the values are valid, but could be anything if outside range. return (date.hour + (date.minute + date.second / 60) / 60) / 24 end local function julian_date(date) -- Return jd, jdz from a Julian or Gregorian calendar date where -- jd = Julian date and its fractional part is zero at noon -- jdz = same, but assume time is 00:00:00 if no time given -- http://www.tondering.dk/claus/cal/julperiod.php#formula -- Testing shows this works for all dates from year -9999 to 9999! -- JDN 0 is the 24-hour period starting at noon UTC on Monday -- 1 January 4713 BC = (-4712, 1, 1) Julian calendar -- 24 November 4714 BC = (-4713, 11, 24) Gregorian calendar local offset local a = floor((14 - date.month)/12) local y = date.year + 4800 - a if date.calendar == 'Julian' then offset = floor(y/4) - 32083 else offset = floor(y/4) - floor(y/100) + floor(y/400) - 32045 end local m = date.month + 12*a - 3 local jd = date.day + floor((153*m + 2)/5) + 365*y + offset if date.hastime then jd = jd + hms(date) - 0.5 return jd, jd end return jd, jd - 0.5 end local function set_date_from_jd(date) -- Set the fields of table date from its Julian date field. -- Return true if date is valid. -- http://www.tondering.dk/claus/cal/julperiod.php#formula -- This handles the proleptic Julian and Gregorian calendars. -- Negative Julian dates are not defined but they work. local calname = date.calendar local low, high -- min/max limits for date ranges −9999-01-01 to 9999-12-31 if calname == 'Gregorian' then low, high = -1930999.5, 5373484.49999 elseif calname == 'Julian' then low, high = -1931076.5, 5373557.49999 else return end local jd = date.jd if not (type(jd) == 'number' and low <= jd and jd <= high) then return end local jdn = floor(jd) if date.hastime then local time = jd - jdn -- 0 <= time < 1 if time >= 0.5 then -- if at or after midnight of next day jdn = jdn + 1 time = time - 0.5 else time = time + 0.5 end date.hour, date.minute, date.second = h_m_s(time) else date.second = 0 date.minute = 0 date.hour = 0 end local b, c if calname == 'Julian' then b = 0 c = jdn + 32082 else -- Gregorian local a = jdn + 32044 b = floor((4*a + 3)/146097) c = a - floor(146097*b/4) end local d = floor((4*c + 3)/1461) local e = c - floor(1461*d/4) local m = floor((5*e + 2)/153) date.day = e - floor((153*m + 2)/5) + 1 date.month = m + 3 - 12*floor(m/10) date.year = 100*b + d - 4800 + floor(m/10) return true end local function fix_numbers(numbers, y, m, d, H, M, S, partial, hastime, calendar) -- Put the result of normalizing the given values in table numbers. -- The result will have valid m, d values if y is valid; caller checks y. -- The logic of PHP mktime is followed where m or d can be zero to mean -- the previous unit, and -1 is the one before that, etc. -- Positive values carry forward. local date if not (1 <= m and m <= 12) then date = Date(y, 1, 1) if not date then return end date = date + ((m - 1) .. 'm') y, m = date.year, date.month end local days_hms if not partial then if hastime and H and M and S then if not (0 <= H and H <= 23 and 0 <= M and M <= 59 and 0 <= S and S <= 59) then days_hms = hms({ hour = H, minute = M, second = S }) end end if days_hms or not (1 <= d and d <= days_in_month(y, m, calendar)) then date = date or Date(y, m, 1) if not date then return end date = date + (d - 1 + (days_hms or 0)) y, m, d = date.year, date.month, date.day if days_hms then H, M, S = date.hour, date.minute, date.second end end end numbers.year = y numbers.month = m numbers.day = d if days_hms then -- Don't set H unless it was valid because a valid H will set hastime. numbers.hour = H numbers.minute = M numbers.second = S end end local function set_date_from_numbers(date, numbers, options) -- Set the fields of table date from numeric values. -- Return true if date is valid. if type(numbers) ~= 'table' then return end local y = numbers.year or date.year local m = numbers.month or date.month local d = numbers.day or date.day local H = numbers.hour local M = numbers.minute or date.minute or 0 local S = numbers.second or date.second or 0 local need_fix if y and m and d then date.partial = nil if not (-9999 <= y and y <= 9999 and 1 <= m and m <= 12 and 1 <= d and d <= days_in_month(y, m, date.calendar)) then if not date.want_fix then return end need_fix = true end elseif y and date.partial then if d or not (-9999 <= y and y <= 9999) then return end if m and not (1 <= m and m <= 12) then if not date.want_fix then return end need_fix = true end else return end if date.partial then H = nil -- ignore any time M = nil S = nil else if H then -- It is not possible to set M or S without also setting H. date.hastime = true else H = 0 end if not (0 <= H and H <= 23 and 0 <= M and M <= 59 and 0 <= S and S <= 59) then if date.want_fix then need_fix = true else return end end end date.want_fix = nil if need_fix then fix_numbers(numbers, y, m, d, H, M, S, date.partial, date.hastime, date.calendar) return set_date_from_numbers(date, numbers, options) end date.year = y -- -9999 to 9999 ('n BC' → year = 1 - n) date.month = m -- 1 to 12 (may be nil if partial) date.day = d -- 1 to 31 (* = nil if partial) date.hour = H -- 0 to 59 (*) date.minute = M -- 0 to 59 (*) date.second = S -- 0 to 59 (*) if type(options) == 'table' then for _, k in ipairs({ 'am', 'era', 'format' }) do if options[k] then date.options[k] = options[k] end end end return true end local function make_option_table(options1, options2) -- If options1 is a string, return a table with its settings, or -- if it is a table, use its settings. -- Missing options are set from table options2 or defaults. -- If a default is used, a flag is set so caller knows the value was not intentionally set. -- Valid option settings are: -- am: 'am', 'a.m.', 'AM', 'A.M.' -- 'pm', 'p.m.', 'PM', 'P.M.' (each has same meaning as corresponding item above) -- era: 'BCMINUS', 'BCNEGATIVE', 'BC', 'B.C.', 'BCE', 'B.C.E.', 'AD', 'A.D.', 'CE', 'C.E.' -- Option am = 'am' does not mean the hour is AM; it means 'am' or 'pm' is used, depending on the hour, -- and am = 'pm' has the same meaning. -- Similarly, era = 'BC' means 'BC' is used if year <= 0. -- BCMINUS displays a MINUS if year < 0 and the display format does not include %{era}. -- BCNEGATIVE is similar but displays a hyphen. local result = { bydefault = {} } if type(options1) == 'table' then result.am = options1.am result.era = options1.era elseif type(options1) == 'string' then -- Example: 'am:AM era:BC' or 'am=AM era=BC'. for item in options1:gmatch('%S+') do local lhs, rhs = item:match('^(%w+)[:=](.+)$') if lhs then result[lhs] = rhs end end end options2 = type(options2) == 'table' and options2 or {} local defaults = { am = 'am', era = 'BC' } for k, v in pairs(defaults) do if not result[k] then if options2[k] then result[k] = options2[k] else result[k] = v result.bydefault[k] = true end end end return result end local ampm_options = { -- lhs = input text accepted as an am/pm option -- rhs = code used internally ['am'] = 'am', ['AM'] = 'AM', ['a.m.'] = 'a.m.', ['A.M.'] = 'A.M.', ['pm'] = 'am', -- same as am ['PM'] = 'AM', ['p.m.'] = 'a.m.', ['P.M.'] = 'A.M.', } local era_text = { -- Text for displaying an era with a positive year (after adjusting -- by replacing year with 1 - year if date.year <= 0). -- options.era = { year<=0 , year>0 } ['BCMINUS'] = { 'BC' , '' , isbc = true, sign = MINUS }, ['BCNEGATIVE'] = { 'BC' , '' , isbc = true, sign = '-' }, ['BC'] = { 'BC' , '' , isbc = true }, ['B.C.'] = { 'B.C.' , '' , isbc = true }, ['BCE'] = { 'BCE' , '' , isbc = true }, ['B.C.E.'] = { 'B.C.E.', '' , isbc = true }, ['AD'] = { 'BC' , 'AD' }, ['A.D.'] = { 'B.C.' , 'A.D.' }, ['CE'] = { 'BCE' , 'CE' }, ['C.E.'] = { 'B.C.E.', 'C.E.' }, } local function get_era_for_year(era, year) return (era_text[era] or era_text['BC'])[year > 0 and 2 or 1] or '' end local function strftime(date, format, options) -- Return date formatted as a string using codes similar to those -- in the C strftime library function. local sformat = string.format local shortcuts = { ['%c'] = '%-I:%M %p %-d %B %-Y %{era}', -- date and time: 2:30 pm 1 April 2016 ['%x'] = '%-d %B %-Y %{era}', -- date: 1 April 2016 ['%X'] = '%-I:%M %p', -- time: 2:30 pm } if shortcuts[format] then format = shortcuts[format] end local codes = { a = { field = 'dayabbr' }, A = { field = 'dayname' }, b = { field = 'monthabbr' }, B = { field = 'monthname' }, u = { fmt = '%d' , field = 'dowiso' }, w = { fmt = '%d' , field = 'dow' }, d = { fmt = '%02d', fmt2 = '%d', field = 'day' }, m = { fmt = '%02d', fmt2 = '%d', field = 'month' }, Y = { fmt = '%04d', fmt2 = '%d', field = 'year' }, H = { fmt = '%02d', fmt2 = '%d', field = 'hour' }, M = { fmt = '%02d', fmt2 = '%d', field = 'minute' }, S = { fmt = '%02d', fmt2 = '%d', field = 'second' }, j = { fmt = '%03d', fmt2 = '%d', field = 'dayofyear' }, I = { fmt = '%02d', fmt2 = '%d', field = 'hour', special = 'hour12' }, p = { field = 'hour', special = 'am' }, } options = make_option_table(options, date.options) local amopt = options.am local eraopt = options.era local function replace_code(spaces, modifier, id) local code = codes[id] if code then local fmt = code.fmt if modifier == '-' and code.fmt2 then fmt = code.fmt2 end local value = date[code.field] if not value then return nil -- an undefined field in a partial date end local special = code.special if special then if special == 'hour12' then value = value % 12 value = value == 0 and 12 or value elseif special == 'am' then local ap = ({ ['a.m.'] = { 'a.m.', 'p.m.' }, ['AM'] = { 'AM', 'PM' }, ['A.M.'] = { 'A.M.', 'P.M.' }, })[ampm_options[amopt]] or { 'am', 'pm' } return (spaces == '' and '' or '&nbsp;') .. (value < 12 and ap[1] or ap[2]) end end if code.field == 'year' then local sign = (era_text[eraopt] or {}).sign if not sign or format:find('%{era}', 1, true) then sign = '' if value <= 0 then value = 1 - value end else if value >= 0 then sign = '' else value = -value end end return spaces .. sign .. sformat(fmt, value) end return spaces .. (fmt and sformat(fmt, value) or value) end end local function replace_property(spaces, id) if id == 'era' then -- Special case so can use local era option. local result = get_era_for_year(eraopt, date.year) if result == '' then return '' end return (spaces == '' and '' or '&nbsp;') .. result end local result = date[id] if type(result) == 'string' then return spaces .. result end if type(result) == 'number' then return spaces .. tostring(result) end if type(result) == 'boolean' then return spaces .. (result and '1' or '0') end -- This occurs if id is an undefined field in a partial date, or is the name of a function. return nil end local PERCENT = '\127PERCENT\127' return (format :gsub('%%%%', PERCENT) :gsub('(%s*)%%{(%w+)}', replace_property) :gsub('(%s*)%%(%-?)(%a)', replace_code) :gsub(PERCENT, '%%') ) end local function _date_text(date, fmt, options) -- Return a formatted string representing the given date. if not is_date(date) then error('date:text: need a date (use "date:text()" with a colon)', 2) end if type(fmt) == 'string' and fmt:match('%S') then if fmt:find('%', 1, true) then return strftime(date, fmt, options) end elseif date.partial then fmt = date.month and 'my' or 'y' else fmt = 'dmy' if date.hastime then fmt = (date.second > 0 and 'hms ' or 'hm ') .. fmt end end local function bad_format() -- For consistency with other format processing, return given format -- (or cleaned format if original was not a string) if invalid. return mw.text.nowiki(fmt) end if date.partial then -- Ignore days in standard formats like 'ymd'. if fmt == 'ym' or fmt == 'ymd' then fmt = date.month and '%Y-%m %{era}' or '%Y %{era}' elseif fmt == 'my' or fmt == 'dmy' or fmt == 'mdy' then fmt = date.month and '%B %-Y %{era}' or '%-Y %{era}' elseif fmt == 'y' then fmt = date.month and '%-Y %{era}' or '%-Y %{era}' else return bad_format() end return strftime(date, fmt, options) end local function hm_fmt() local plain = make_option_table(options, date.options).bydefault.am return plain and '%H:%M' or '%-I:%M %p' end local need_time = date.hastime local t = collection() for item in fmt:gmatch('%S+') do local f if item == 'hm' then f = hm_fmt() need_time = false elseif item == 'hms' then f = '%H:%M:%S' need_time = false elseif item == 'ymd' then f = '%Y-%m-%d %{era}' elseif item == 'mdy' then f = '%B %-d, %-Y %{era}' elseif item == 'dmy' then f = '%-d %B %-Y %{era}' else return bad_format() end t:add(f) end fmt = t:join(' ') if need_time then fmt = hm_fmt() .. ' ' .. fmt end return strftime(date, fmt, options) end local day_info = { -- 0=Sun to 6=Sat [0] = { 'อา', 'วันอาทิตย์' }, { 'จ', 'วันจันทร์' }, { 'อ', 'วันอังคาร' }, { 'พ', 'วันพุธ' }, { 'พฤ', 'วันพฤหัสบดี' }, { 'ศ', 'วันศุกร์' }, { 'ส', 'วันเสาร์' }, } local month_info = { -- 1=Jan to 12=Dec { 'ม.ค.', 'มกราคม' }, { 'ก.พ.', 'กุมภาพันธ์' }, { 'มี.ค.', 'มีนาคม' }, { 'เม.ย.', 'เมษายน' }, { 'พ.ค.', 'พฤษภาคม' }, { 'มิ.ย.', 'มิถุนายน' }, { 'ก.ค.', 'กรกฎาคม' }, { 'ส.ค.', 'สิงหาคม' }, { 'ก.ย.', 'กันยายน' }, { 'ต.ค.', 'ตุลาคม' }, { 'พ.ย.', 'พฤศจิกายน' }, { 'ธ.ค.', 'ธันวาคม' }, } local function name_to_number(text, translate) if type(text) == 'string' then return translate[text:lower()] end end local function day_number(text) return name_to_number(text, { sun = 0, sunday = 0, mon = 1, monday = 1, tue = 2, tuesday = 2, wed = 3, wednesday = 3, thu = 4, thursday = 4, fri = 5, friday = 5, sat = 6, saturday = 6, }) end local function month_number(text) return name_to_number(text, { jan = 1, january = 1, feb = 2, february = 2, mar = 3, march = 3, apr = 4, april = 4, may = 5, jun = 6, june = 6, jul = 7, july = 7, aug = 8, august = 8, sep = 9, september = 9, sept = 9, oct = 10, october = 10, nov = 11, november = 11, dec = 12, december = 12, }) end local function _list_text(list, fmt) -- Return a list of formatted strings from a list of dates. if not type(list) == 'table' then error('date:list:text: need "list:text()" with a colon', 2) end local result = { join = _list_join } for i, date in ipairs(list) do result[i] = date:text(fmt) end return result end local function _date_list(date, spec) -- Return a possibly empty numbered table of dates meeting the specification. -- Dates in the list are in ascending order (oldest date first). -- The spec should be a string of form "<count> <day> <op>" -- where each item is optional and -- count = number of items wanted in list -- day = abbreviation or name such as Mon or Monday -- op = >, >=, <, <= (default is > meaning after date) -- If no count is given, the list is for the specified days in date's month. -- The default day is date's day. -- The spec can also be a positive or negative number: -- -5 is equivalent to '5 <' -- 5 is equivalent to '5' which is '5 >' if not is_date(date) then error('date:list: need a date (use "date:list()" with a colon)', 2) end local list = { text = _list_text } if date.partial then return list end local count, offset, operation local ops = { ['>='] = { before = false, include = true }, ['>'] = { before = false, include = false }, ['<='] = { before = true , include = true }, ['<'] = { before = true , include = false }, } if spec then if type(spec) == 'number' then count = floor(spec + 0.5) if count < 0 then count = -count operation = ops['<'] end elseif type(spec) == 'string' then local num, day, op = spec:match('^%s*(%d*)%s*(%a*)%s*([<>=]*)%s*$') if not num then return list end if num ~= '' then count = tonumber(num) end if day ~= '' then local dow = day_number(day:gsub('[sS]$', '')) -- accept plural days if not dow then return list end offset = dow - date.dow end operation = ops[op] else return list end end offset = offset or 0 operation = operation or ops['>'] local datefrom, dayfirst, daylast if operation.before then if offset > 0 or (offset == 0 and not operation.include) then offset = offset - 7 end if count then if count > 1 then offset = offset - 7*(count - 1) end datefrom = date + offset else daylast = date.day + offset dayfirst = daylast % 7 if dayfirst == 0 then dayfirst = 7 end end else if offset < 0 or (offset == 0 and not operation.include) then offset = offset + 7 end if count then datefrom = date + offset else dayfirst = date.day + offset daylast = date.monthdays end end if not count then if daylast < dayfirst then return list end count = floor((daylast - dayfirst)/7) + 1 datefrom = Date(date, {day = dayfirst}) end for i = 1, count do if not datefrom then break end -- exceeds date limits list[i] = datefrom datefrom = datefrom + 7 end return list end -- A table to get the current date/time (UTC), but only if needed. local current = setmetatable({}, { __index = function (self, key) local d = os.date('!*t') self.year = d.year self.month = d.month self.day = d.day self.hour = d.hour self.minute = d.min self.second = d.sec return rawget(self, key) end }) local function extract_date(newdate, text) -- Parse the date/time in text and return n, o where -- n = table of numbers with date/time fields -- o = table of options for AM/PM or AD/BC or format, if any -- or return nothing if date is known to be invalid. -- Caller determines if the values in n are valid. -- A year must be positive ('1' to '9999'); use 'BC' for BC. -- In a y-m-d string, the year must be four digits to avoid ambiguity -- ('0001' to '9999'). The only way to enter year <= 0 is by specifying -- the date as three numeric parameters like ymd Date(-1, 1, 1). -- Dates of form d/m/y, m/d/y, y/m/d are rejected as potentially ambiguous. local date, options = {}, {} if text:sub(-1) == 'Z' then -- Extract date/time from a Wikidata timestamp. -- The year can be 1 to 16 digits but this module handles 1 to 4 digits only. -- Examples: '+2016-06-21T14:30:00Z', '-0000000180-00-00T00:00:00Z'. local sign, y, m, d, H, M, S = text:match('^([+%-])(%d+)%-(%d%d)%-(%d%d)T(%d%d):(%d%d):(%d%d)Z$') if sign then y = tonumber(y) if sign == '-' and y > 0 then y = -y end if y <= 0 then options.era = 'BCE' end date.year = y m = tonumber(m) d = tonumber(d) H = tonumber(H) M = tonumber(M) S = tonumber(S) if m == 0 then newdate.partial = true return date, options end date.month = m if d == 0 then newdate.partial = true return date, options end date.day = d if H > 0 or M > 0 or S > 0 then date.hour = H date.minute = M date.second = S end return date, options end return end local function extract_ymd(item) -- Called when no day or month has been set. local y, m, d = item:match('^(%d%d%d%d)%-(%w+)%-(%d%d?)$') if y then if date.year then return end if m:match('^%d%d?$') then m = tonumber(m) else m = month_number(m) end if m then date.year = tonumber(y) date.month = m date.day = tonumber(d) return true end end end local function extract_day_or_year(item) -- Called when a day would be valid, or -- when a year would be valid if no year has been set and partial is set. local number, suffix = item:match('^(%d%d?%d?%d?)(.*)$') if number then local n = tonumber(number) if #number <= 2 and n <= 31 then suffix = suffix:lower() if suffix == '' or suffix == 'st' or suffix == 'nd' or suffix == 'rd' or suffix == 'th' then date.day = n return true end elseif suffix == '' and newdate.partial and not date.year then date.year = n return true end end end local function extract_month(item) -- A month must be given as a name or abbreviation; a number could be ambiguous. local m = month_number(item) if m then date.month = m return true end end local function extract_time(item) local h, m, s = item:match('^(%d%d?):(%d%d)(:?%d*)$') if date.hour or not h then return end if s ~= '' then s = s:match('^:(%d%d)$') if not s then return end end date.hour = tonumber(h) date.minute = tonumber(m) date.second = tonumber(s) -- nil if empty string return true end local item_count = 0 local index_time local function set_ampm(item) local H = date.hour if H and not options.am and index_time + 1 == item_count then options.am = ampm_options[item] -- caller checked this is not nil if item:match('^[Aa]') then if not (1 <= H and H <= 12) then return end if H == 12 then date.hour = 0 end else if not (1 <= H and H <= 23) then return end if H <= 11 then date.hour = H + 12 end end return true end end for item in text:gsub(',', ' '):gsub('&nbsp;', ' '):gmatch('%S+') do item_count = item_count + 1 if era_text[item] then -- Era is accepted in peculiar places. if options.era then return end options.era = item elseif ampm_options[item] then if not set_ampm(item) then return end elseif item:find(':', 1, true) then if not extract_time(item) then return end index_time = item_count elseif date.day and date.month then if date.year then return -- should be nothing more so item is invalid end if not item:match('^(%d%d?%d?%d?)$') then return end date.year = tonumber(item) elseif date.day then if not extract_month(item) then return end elseif date.month then if not extract_day_or_year(item) then return end elseif extract_month(item) then options.format = 'mdy' elseif extract_ymd(item) then options.format = 'ymd' elseif extract_day_or_year(item) then if date.day then options.format = 'dmy' end else return end end if not date.year or date.year == 0 then return end local era = era_text[options.era] if era and era.isbc then date.year = 1 - date.year end return date, options end local function autofill(date1, date2) -- Fill any missing month or day in each date using the -- corresponding component from the other date, if present, -- or with 1 if both dates are missing the month or day. -- This gives a good result for calculating the difference -- between two partial dates when no range is wanted. -- Return filled date1, date2 (two full dates). local function filled(a, b) -- Return date a filled, if necessary, with month and/or day from date b. -- The filled day is truncated to fit the number of days in the month. local fillmonth, fillday if not a.month then fillmonth = b.month or 1 end if not a.day then fillday = b.day or 1 end if fillmonth or fillday then -- need to create a new date a = Date(a, { month = fillmonth, day = math.min(fillday or a.day, days_in_month(a.year, fillmonth or a.month, a.calendar)) }) end return a end return filled(date1, date2), filled(date2, date1) end local function date_add_sub(lhs, rhs, is_sub) -- Return a new date from calculating (lhs + rhs) or (lhs - rhs), -- or return nothing if invalid. -- The result is nil if the calculated date exceeds allowable limits. -- Caller ensures that lhs is a date; its properties are copied for the new date. if lhs.partial then -- Adding to a partial is not supported. -- Can subtract a date or partial from a partial, but this is not called for that. return end local function is_prefix(text, word, minlen) local n = #text return (minlen or 1) <= n and n <= #word and text == word:sub(1, n) end local function do_days(n) local forcetime, jd if floor(n) == n then jd = lhs.jd else forcetime = not lhs.hastime jd = lhs.jdz end jd = jd + (is_sub and -n or n) if forcetime then jd = tostring(jd) if not jd:find('.', 1, true) then jd = jd .. '.0' end end return Date(lhs, 'juliandate', jd) end if type(rhs) == 'number' then -- Add/subtract days, including fractional days. return do_days(rhs) end if type(rhs) == 'string' then -- rhs is a single component like '26m' or '26 months' (with optional sign). -- Fractions like '3.25d' are accepted for the units which are handled as days. local sign, numstr, id = rhs:match('^%s*([+-]?)([%d%.]+)%s*(%a+)$') if sign then if sign == '-' then is_sub = not (is_sub and true or false) end local y, m, days local num = tonumber(numstr) if not num then return end id = id:lower() if is_prefix(id, 'years') then y = num m = 0 elseif is_prefix(id, 'months') then y = floor(num / 12) m = num % 12 elseif is_prefix(id, 'weeks') then days = num * 7 elseif is_prefix(id, 'days') then days = num elseif is_prefix(id, 'hours') then days = num / 24 elseif is_prefix(id, 'minutes', 3) then days = num / (24 * 60) elseif is_prefix(id, 'seconds') then days = num / (24 * 3600) else return end if days then return do_days(days) end if numstr:find('.', 1, true) then return end if is_sub then y = -y m = -m end assert(-11 <= m and m <= 11) y = lhs.year + y m = lhs.month + m if m > 12 then y = y + 1 m = m - 12 elseif m < 1 then y = y - 1 m = m + 12 end local d = math.min(lhs.day, days_in_month(y, m, lhs.calendar)) return Date(lhs, y, m, d) end end if is_diff(rhs) then local days = rhs.age_days if (is_sub or false) ~= (rhs.isnegative or false) then days = -days end return lhs + days end end local full_date_only = { dayabbr = true, dayname = true, dow = true, dayofweek = true, dowiso = true, dayofweekiso = true, dayofyear = true, gsd = true, juliandate = true, jd = true, jdz = true, jdnoon = true, } -- Metatable for a date's calculated fields. local datemt = { __index = function (self, key) if rawget(self, 'partial') then if full_date_only[key] then return end if key == 'monthabbr' or key == 'monthdays' or key == 'monthname' then if not self.month then return end end end local value if key == 'dayabbr' then value = day_info[self.dow][1] elseif key == 'dayname' then value = day_info[self.dow][2] elseif key == 'dow' then value = (self.jdnoon + 1) % 7 -- day-of-week 0=Sun to 6=Sat elseif key == 'dayofweek' then value = self.dow elseif key == 'dowiso' then value = (self.jdnoon % 7) + 1 -- ISO day-of-week 1=Mon to 7=Sun elseif key == 'dayofweekiso' then value = self.dowiso elseif key == 'dayofyear' then local first = Date(self.year, 1, 1, self.calendar).jdnoon value = self.jdnoon - first + 1 -- day-of-year 1 to 366 elseif key == 'era' then -- Era text (never a negative sign) from year and options. value = get_era_for_year(self.options.era, self.year) elseif key == 'format' then value = self.options.format or 'dmy' elseif key == 'gsd' then -- GSD = 1 from 00:00:00 to 23:59:59 on 1 January 1 AD Gregorian calendar, -- which is from jd 1721425.5 to 1721426.49999. value = floor(self.jd - 1721424.5) elseif key == 'juliandate' or key == 'jd' or key == 'jdz' then local jd, jdz = julian_date(self) rawset(self, 'juliandate', jd) rawset(self, 'jd', jd) rawset(self, 'jdz', jdz) return key == 'jdz' and jdz or jd elseif key == 'jdnoon' then -- Julian date at noon (an integer) on the calendar day when jd occurs. value = floor(self.jd + 0.5) elseif key == 'isleapyear' then value = is_leap_year(self.year, self.calendar) elseif key == 'monthabbr' then value = month_info[self.month][1] elseif key == 'monthdays' then value = days_in_month(self.year, self.month, self.calendar) elseif key == 'monthname' then value = month_info[self.month][2] end if value ~= nil then rawset(self, key, value) return value end end, } -- Date operators. local function mt_date_add(lhs, rhs) if not is_date(lhs) then lhs, rhs = rhs, lhs -- put date on left (it must be a date for this to have been called) end return date_add_sub(lhs, rhs) end local function mt_date_sub(lhs, rhs) if is_date(lhs) then if is_date(rhs) then return DateDiff(lhs, rhs) end return date_add_sub(lhs, rhs, true) end end local function mt_date_concat(lhs, rhs) return tostring(lhs) .. tostring(rhs) end local function mt_date_tostring(self) return self:text() end local function mt_date_eq(lhs, rhs) -- Return true if dates identify same date/time where, for example, -- Date(-4712, 1, 1, 'Julian') == Date(-4713, 11, 24, 'Gregorian') is true. -- This is called only if lhs and rhs have the same type and the same metamethod. if lhs.partial or rhs.partial then -- One date is partial; the other is a partial or a full date. -- The months may both be nil, but must be the same. return lhs.year == rhs.year and lhs.month == rhs.month and lhs.calendar == rhs.calendar end return lhs.jdz == rhs.jdz end local function mt_date_lt(lhs, rhs) -- Return true if lhs < rhs, for example, -- Date('1 Jan 2016') < Date('06:00 1 Jan 2016') is true. -- This is called only if lhs and rhs have the same type and the same metamethod. if lhs.partial or rhs.partial then -- One date is partial; the other is a partial or a full date. if lhs.calendar ~= rhs.calendar then return lhs.calendar == 'Julian' end if lhs.partial then lhs = lhs.partial.first end if rhs.partial then rhs = rhs.partial.first end end return lhs.jdz < rhs.jdz end --[[ Examples of syntax to construct a date: Date(y, m, d, 'julian') default calendar is 'gregorian' Date(y, m, d, H, M, S, 'julian') Date('juliandate', jd, 'julian') if jd contains "." text output includes H:M:S Date('currentdate') Date('currentdatetime') Date('1 April 1995', 'julian') parse date from text Date('1 April 1995 AD', 'julian') using an era sets a flag to do the same for output Date('04:30:59 1 April 1995', 'julian') Date(date) copy of an existing date Date(date, t) same, updated with y,m,d,H,M,S fields from table t Date(t) date with y,m,d,H,M,S fields from table t ]] function Date(...) -- for forward declaration above -- Return a table holding a date assuming a uniform calendar always applies -- (proleptic Gregorian calendar or proleptic Julian calendar), or -- return nothing if date is invalid. -- A partial date has a valid year, however its month may be nil, and -- its day and time fields are nil. -- Field partial is set to false (if a full date) or a table (if a partial date). local calendars = { julian = 'Julian', gregorian = 'Gregorian' } local newdate = { _id = uniq, calendar = 'Gregorian', -- default is Gregorian calendar hastime = false, -- true if input sets a time hour = 0, -- always set hour/minute/second so don't have to handle nil minute = 0, second = 0, options = {}, list = _date_list, subtract = function (self, rhs, options) return DateDiff(self, rhs, options) end, text = _date_text, } local argtype, datetext, is_copy, jd_number, tnums local numindex = 0 local numfields = { 'year', 'month', 'day', 'hour', 'minute', 'second' } local numbers = {} for _, v in ipairs({...}) do v = strip_to_nil(v) local vlower = type(v) == 'string' and v:lower() or nil if v == nil then -- Ignore empty arguments after stripping so modules can directly pass template parameters. elseif calendars[vlower] then newdate.calendar = calendars[vlower] elseif vlower == 'partial' then newdate.partial = true elseif vlower == 'fix' then newdate.want_fix = true elseif is_date(v) then -- Copy existing date (items can be overridden by other arguments). if is_copy or tnums then return end is_copy = true newdate.calendar = v.calendar newdate.partial = v.partial newdate.hastime = v.hastime newdate.options = v.options newdate.year = v.year newdate.month = v.month newdate.day = v.day newdate.hour = v.hour newdate.minute = v.minute newdate.second = v.second elseif type(v) == 'table' then if tnums then return end tnums = {} local tfields = { year=1, month=1, day=1, hour=2, minute=2, second=2 } for tk, tv in pairs(v) do if tfields[tk] then tnums[tk] = tonumber(tv) end if tfields[tk] == 2 then newdate.hastime = true end end else local num = tonumber(v) if not num and argtype == 'setdate' and numindex == 1 then num = month_number(v) end if num then if not argtype then argtype = 'setdate' end if argtype == 'setdate' and numindex < 6 then numindex = numindex + 1 numbers[numfields[numindex]] = num elseif argtype == 'juliandate' and not jd_number then jd_number = num if type(v) == 'string' then if v:find('.', 1, true) then newdate.hastime = true end elseif num ~= floor(num) then -- The given value was a number. The time will be used -- if the fractional part is nonzero. newdate.hastime = true end else return end elseif argtype then return elseif type(v) == 'string' then if v == 'currentdate' or v == 'currentdatetime' or v == 'juliandate' then argtype = v else argtype = 'datetext' datetext = v end else return end end end if argtype == 'datetext' then if tnums or not set_date_from_numbers(newdate, extract_date(newdate, datetext)) then return end elseif argtype == 'juliandate' then newdate.partial = nil newdate.jd = jd_number if not set_date_from_jd(newdate) then return end elseif argtype == 'currentdate' or argtype == 'currentdatetime' then newdate.partial = nil newdate.year = current.year newdate.month = current.month newdate.day = current.day if argtype == 'currentdatetime' then newdate.hour = current.hour newdate.minute = current.minute newdate.second = current.second newdate.hastime = true end newdate.calendar = 'Gregorian' -- ignore any given calendar name elseif argtype == 'setdate' then if tnums or not set_date_from_numbers(newdate, numbers) then return end elseif not (is_copy or tnums) then return end if tnums then newdate.jd = nil -- force recalculation in case jd was set before changes from tnums if not set_date_from_numbers(newdate, tnums) then return end end if newdate.partial then local year = newdate.year local month = newdate.month local first = Date(year, month or 1, 1, newdate.calendar) month = month or 12 local last = Date(year, month, days_in_month(year, month), newdate.calendar) newdate.partial = { first = first, last = last } else newdate.partial = false -- avoid index lookup end setmetatable(newdate, datemt) local readonly = {} local mt = { __index = newdate, __newindex = function(t, k, v) error('date.' .. tostring(k) .. ' is read-only', 2) end, __add = mt_date_add, __sub = mt_date_sub, __concat = mt_date_concat, __tostring = mt_date_tostring, __eq = mt_date_eq, __lt = mt_date_lt, } return setmetatable(readonly, mt) end local function _diff_age(diff, code, options) -- Return a tuple of integer values from diff as specified by code, except that -- each integer may be a list of two integers for a diff with a partial date, or -- return nil if the code is not supported. -- If want round, the least significant unit is rounded to nearest whole unit. -- For a duration, an extra day is added. local wantround, wantduration, wantrange if type(options) == 'table' then wantround = options.round wantduration = options.duration wantrange = options.range else wantround = options end if not is_diff(diff) then local f = wantduration and 'duration' or 'age' error(f .. ': need a date difference (use "diff:' .. f .. '()" with a colon)', 2) end if diff.partial then -- Ignore wantround, wantduration. local function choose(v) if type(v) == 'table' then if not wantrange or v[1] == v[2] then -- Example: Date('partial', 2005) - Date('partial', 2001) gives -- diff.years = { 3, 4 } to show the range of possible results. -- If do not want a range, choose the second value as more expected. return v[2] end end return v end if code == 'ym' or code == 'ymd' then if not wantrange and diff.iszero then -- This avoids an unexpected result such as -- Date('partial', 2001) - Date('partial', 2001) -- giving diff = { years = 0, months = { 0, 11 } } -- which would be reported as 0 years and 11 months. return 0, 0 end return choose(diff.partial.years), choose(diff.partial.months) end if code == 'y' then return choose(diff.partial.years) end if code == 'm' or code == 'w' or code == 'd' then return choose({ diff.partial.mindiff:age(code), diff.partial.maxdiff:age(code) }) end return nil end local extra_days = wantduration and 1 or 0 if code == 'wd' or code == 'w' or code == 'd' then local offset = wantround and 0.5 or 0 local days = diff.age_days + extra_days if code == 'wd' or code == 'd' then days = floor(days + offset) if code == 'd' then return days end return floor(days/7), days % 7 end return floor(days/7 + offset) end local H, M, S = diff.hours, diff.minutes, diff.seconds if code == 'dh' or code == 'dhm' or code == 'dhms' or code == 'h' or code == 'hm' or code == 'hms' or code == 'M' or code == 's' then local days = floor(diff.age_days + extra_days) local inc_hour if wantround then if code == 'dh' or code == 'h' then if M >= 30 then inc_hour = true end elseif code == 'dhm' or code == 'hm' then if S >= 30 then M = M + 1 if M >= 60 then M = 0 inc_hour = true end end elseif code == 'M' then if S >= 30 then M = M + 1 end else -- Nothing needed because S is an integer. end if inc_hour then H = H + 1 if H >= 24 then H = 0 days = days + 1 end end end if code == 'dh' or code == 'dhm' or code == 'dhms' then if code == 'dh' then return days, H elseif code == 'dhm' then return days, H, M else return days, H, M, S end end local hours = days * 24 + H if code == 'h' then return hours elseif code == 'hm' then return hours, M elseif code == 'M' or code == 's' then M = hours * 60 + M if code == 'M' then return M end return M * 60 + S end return hours, M, S end if wantround then local inc_hour if code == 'ymdh' or code == 'ymwdh' then if M >= 30 then inc_hour = true end elseif code == 'ymdhm' or code == 'ymwdhm' then if S >= 30 then M = M + 1 if M >= 60 then M = 0 inc_hour = true end end elseif code == 'ymd' or code == 'ymwd' or code == 'yd' or code == 'md' then if H >= 12 then extra_days = extra_days + 1 end end if inc_hour then H = H + 1 if H >= 24 then H = 0 extra_days = extra_days + 1 end end end local y, m, d = diff.years, diff.months, diff.days if extra_days > 0 then d = d + extra_days if d > 28 or code == 'yd' then -- Recalculate in case have passed a month. diff = diff.date1 + extra_days - diff.date2 y, m, d = diff.years, diff.months, diff.days end end if code == 'ymd' then return y, m, d elseif code == 'yd' then if y > 0 then -- It is known that diff.date1 > diff.date2. diff = diff.date1 - (diff.date2 + (y .. 'y')) end return y, floor(diff.age_days) elseif code == 'md' then return y * 12 + m, d elseif code == 'ym' or code == 'm' then if wantround then if d >= 16 then m = m + 1 if m >= 12 then m = 0 y = y + 1 end end end if code == 'ym' then return y, m end return y * 12 + m elseif code == 'ymw' then local weeks = floor(d/7) if wantround then local days = d % 7 if days > 3 or (days == 3 and H >= 12) then weeks = weeks + 1 end end return y, m, weeks elseif code == 'ymwd' then return y, m, floor(d/7), d % 7 elseif code == 'ymdh' then return y, m, d, H elseif code == 'ymwdh' then return y, m, floor(d/7), d % 7, H elseif code == 'ymdhm' then return y, m, d, H, M elseif code == 'ymwdhm' then return y, m, floor(d/7), d % 7, H, M end if code == 'y' then if wantround and m >= 6 then y = y + 1 end return y end return nil end local function _diff_duration(diff, code, options) if type(options) ~= 'table' then options = { round = options } end options.duration = true return _diff_age(diff, code, options) end -- Metatable for some operations on date differences. diffmt = { -- for forward declaration above __concat = function (lhs, rhs) return tostring(lhs) .. tostring(rhs) end, __tostring = function (self) return tostring(self.age_days) end, __index = function (self, key) local value if key == 'age_days' then if rawget(self, 'partial') then local function jdz(date) return (date.partial and date.partial.first or date).jdz end value = jdz(self.date1) - jdz(self.date2) else value = self.date1.jdz - self.date2.jdz end end if value ~= nil then rawset(self, key, value) return value end end, } function DateDiff(date1, date2, options) -- for forward declaration above -- Return a table with the difference between two dates (date1 - date2). -- The difference is negative if date1 is older than date2. -- Return nothing if invalid. -- If d = date1 - date2 then -- date1 = date2 + d -- If date1 >= date2 and the dates have no H:M:S time specified then -- date1 = date2 + (d.years..'y') + (d.months..'m') + d.days -- where the larger time units are added first. -- The result of Date(2015,1,x) + '1m' is Date(2015,2,28) for -- x = 28, 29, 30, 31. That means, for example, -- d = Date(2015,3,3) - Date(2015,1,31) -- gives d.years, d.months, d.days = 0, 1, 3 (excluding date1). if not (is_date(date1) and is_date(date2) and date1.calendar == date2.calendar) then return end local wantfill if type(options) == 'table' then wantfill = options.fill end local isnegative = false local iszero = false if date1 < date2 then isnegative = true date1, date2 = date2, date1 elseif date1 == date2 then iszero = true end -- It is known that date1 >= date2 (period is from date2 to date1). if date1.partial or date2.partial then -- Two partial dates might have timelines: ---------------------A=================B--- date1 is from A to B inclusive --------C=======D-------------------------- date2 is from C to D inclusive -- date1 > date2 iff A > C (date1.partial.first > date2.partial.first) -- The periods can overlap ('April 2001' - '2001'): -------------A===B------------------------- A=2001-04-01 B=2001-04-30 --------C=====================D------------ C=2001-01-01 D=2001-12-31 if wantfill then date1, date2 = autofill(date1, date2) else local function zdiff(date1, date2) local diff = date1 - date2 if diff.isnegative then return date1 - date1 -- a valid diff in case we call its methods end return diff end local function getdate(date, which) return date.partial and date.partial[which] or date end local maxdiff = zdiff(getdate(date1, 'last'), getdate(date2, 'first')) local mindiff = zdiff(getdate(date1, 'first'), getdate(date2, 'last')) local years, months if maxdiff.years == mindiff.years then years = maxdiff.years if maxdiff.months == mindiff.months then months = maxdiff.months else months = { mindiff.months, maxdiff.months } end else years = { mindiff.years, maxdiff.years } end return setmetatable({ date1 = date1, date2 = date2, partial = { years = years, months = months, maxdiff = maxdiff, mindiff = mindiff, }, isnegative = isnegative, iszero = iszero, age = _diff_age, duration = _diff_duration, }, diffmt) end end local y1, m1 = date1.year, date1.month local y2, m2 = date2.year, date2.month local years = y1 - y2 local months = m1 - m2 local d1 = date1.day + hms(date1) local d2 = date2.day + hms(date2) local days, time if d1 >= d2 then days = d1 - d2 else months = months - 1 -- Get days in previous month (before the "to" date) given December has 31 days. local dpm = m1 > 1 and days_in_month(y1, m1 - 1, date1.calendar) or 31 if d2 >= dpm then days = d1 - hms(date2) else days = dpm - d2 + d1 end end if months < 0 then years = years - 1 months = months + 12 end days, time = math.modf(days) local H, M, S = h_m_s(time) return setmetatable({ date1 = date1, date2 = date2, partial = false, -- avoid index lookup years = years, months = months, days = days, hours = H, minutes = M, seconds = S, isnegative = isnegative, iszero = iszero, age = _diff_age, duration = _diff_duration, }, diffmt) end return { _current = current, _Date = Date, _days_in_month = days_in_month, } 78ea3faee09a817215e1595430285da8cbcf4db9 มอดูล:Age 828 43 108 73 2023-10-05T13:51:48Z PeachFullzZ 2 Scribunto text/plain -- Implement various "age of" and other date-related templates. local mtext = { -- Message and other text that should be localized. -- Also need to localize text in table names in function dateDifference. ['mt-bad-param1'] = 'พารามิเตอร์ไม่ถูกต้อง $1', ['mt-bad-param2'] = 'พารามิเตอร์ $1=$2 ไม่ถูกต้อง', ['mt-bad-show'] = 'พารามิเตอร์ show=$1 ไม่รองรับที่นี่', ['mt-cannot-add'] = 'ไม่สามารถเพิ่ม "$1"', ['mt-conflicting-show'] = 'แสดงพารามิเตอร์=$1 ขัดแย้งกับชุด=$2', ['mt-date-wrong-order'] = 'วันที่สองต้องช้ากว่าวันแรก', ['mt-dd-future'] = 'วันที่เสียชีวิต (วันแรก) ต้องไม่อยู่ในอนาคต', ['mt-dd-wrong-order'] = 'วันที่เสียชีวิต (วันแรก) ต้องช้ากว่าวันเกิด (วันที่สอง)', ['mt-invalid-bd-age'] = 'วันเกิดไม่ถูกต้องสำหรับการคำนวณอายุ', ['mt-invalid-dates-age'] = 'วันที่ไม่ถูกต้องในการคำนวณอายุ', ['mt-invalid-end'] = 'วันที่สิ้นสุดไม่ถูกต้องในพารามิเตอร์ที่สอง', ['mt-invalid-start'] = 'วันที่เริ่มต้นไม่ถูกต้องในพารามิเตอร์ตัวแรก', ['mt-need-jdn'] = 'ต้องการหมายเลขวันที่จูเลียนที่ถูกต้อง', ['mt-need-valid-bd'] = 'ต้องการวันเกิดที่ถูกต้อง: ปี เดือน วัน', ['mt-need-valid-bd2'] = 'ต้องการวันเกิดที่ถูกต้อง (วันที่สอง): ปี เดือน วัน', ['mt-need-valid-date'] = 'ต้องการวันที่ที่ถูกต้อง', ['mt-need-valid-dd'] = 'ต้องการวันเสียชีวิตที่ถูกต้อง (วันแรก): ปี เดือน วัน', ['mt-need-valid-ymd'] = 'ต้องการปี เดือน วันที่ถูกต้อง', ['mt-need-valid-ymd-current'] = 'ต้องการปี|เดือน|วันหรือ "วันที่ปัจจุบัน" ที่ถูกต้อง', ['mt-need-valid-ymd2'] = 'วันที่สองควรเป็นปี เดือน วัน', ['mt-template-bad-name'] = 'ชื่อแม่แบบที่ระบุไม่ถูกต้อง', ['mt-template-x'] = 'แม่แบบที่เรียกใช้ต้องมี "|template=x" โดยที่ x คือการดำเนินการที่ต้องการ', ['txt-and'] = ' ', ['txt-or'] = '&nbsp;หรือ ', ['txt-category'] = 'หมวดหมู่:อายุผิดพลาด', ['txt-comma-and'] = ' ', ['txt-error'] = 'ผิดพลาด: ', ['txt-format-default'] = 'df', -- 'df' (day first = dmy) or 'mf' (month first = mdy) ['txt-module-convertnumeric'] = 'มอดูล:ConvertNumeric', ['txt-module-date'] = 'มอดูล:Date', ['txt-sandbox'] = 'sandbox', ['txt-bda'] = '<span style="display:none"> (<span class="bday">$1</span>) </span>$2<span class="noprint ForceAgeToShow"> ($3)</span>', ['txt-dda'] = '$2<span style="display:none">($1)</span> ($3)', ['txt-bda-disp'] = 'disp_age', -- disp_raw → age is a number only; disp_age → age is a number and unit (normally years but months or days if very young) ['txt-dda-disp'] = 'disp_age', ['txt-dmy'] = '%-d %B ค.ศ. %-Y', ['txt-mdy'] = '%B %-d, %-Y', } local isWarning = { ['mt-bad-param1'] = true, } local translate, from_en, to_en, isZero if translate then -- Functions to translate from en to local language and reverse go here. -- See example at [[:bn:Module:বয়স]]. else from_en = function (text) return text end isZero = function (text) return tonumber(text) == 0 end end local _Date, _currentDate local function getExports(frame) -- Return objects exported from the date module or its sandbox. if not _Date then local sandbox = frame:getTitle():find(mtext['txt-sandbox'], 1, true) and ('/' .. mtext['txt-sandbox']) or '' local datemod = require(mtext['txt-module-date'] .. sandbox) local realDate = datemod._Date _currentDate = datemod._current if to_en then _Date = function (...) local args = {} for i, v in ipairs({...}) do args[i] = to_en(v) end return realDate(unpack(args)) end else _Date = realDate end end return _Date, _currentDate end local Collection -- a table to hold items Collection = { add = function (self, item) if item ~= nil then self.n = self.n + 1 self[self.n] = item end end, join = function (self, sep) return table.concat(self, sep) end, remove = function (self, pos) if self.n > 0 and (pos == nil or (0 < pos and pos <= self.n)) then self.n = self.n - 1 return table.remove(self, pos) end end, sort = function (self, comp) table.sort(self, comp) end, new = function () return setmetatable({n = 0}, Collection) end } Collection.__index = Collection local function stripToNil(text) -- If text is a string, return its trimmed content, or nil if empty. -- Otherwise return text (which may, for example, be nil). if type(text) == 'string' then text = text:match('(%S.-)%s*$') end return text end local function dateFormat(args) -- Return string for wanted date format. local default = mtext['txt-format-default'] local other = default == 'df' and 'mf' or 'df' local wanted = stripToNil(args[other]) and other or default return wanted == 'df' and mtext['txt-dmy'] or mtext['txt-mdy'] end local function substituteParameters(text, ...) -- Return text after substituting any given parameters for $1, $2, etc. return mw.message.newRawMessage(text, ...):plain() end local function yes(parameter) -- Return true if parameter should be interpreted as "yes". -- Do not want to accept mixed upper/lowercase unless done by current templates. -- Need to accept "on" because "round=on" is wanted. return ({ y = true, yes = true, on = true })[parameter] end local function message(msg, ...) -- Return formatted message text for an error or warning. local function getText(msg) return mtext[msg] or error('Bug: message "' .. tostring(msg) .. '" not defined') end local categories = { error = mtext['txt-category'], warning = mtext['txt-category'], } local a, b, k, category local text = substituteParameters(getText(msg), ...) if isWarning[msg] then a = '<sup>[<i>' b = '</i>]</sup>' k = 'warning' else a = '<strong class="error">' .. getText('txt-error') b = '</strong>' k = 'error' end if mw.title.getCurrentTitle():inNamespaces(0) then -- Category only in namespaces: 0=article. category = '[[' .. categories[k] .. ']]' end return a .. mw.text.nowiki(text) .. b .. (category or '') end local function formatNumber(number) -- Return the given number formatted with commas as group separators, -- given that the number is an integer. local numstr = tostring(number) local length = #numstr local places = Collection.new() local pos = 0 repeat places:add(pos) pos = pos + 3 until pos >= length places:add(length) local groups = Collection.new() for i = places.n, 2, -1 do local p1 = length - places[i] + 1 local p2 = length - places[i - 1] groups:add(numstr:sub(p1, p2)) end return groups:join(',') end local function spellNumber(number, options, i) -- Return result of spelling number, or -- return number (as a string) if cannot spell it. -- i == 1 for the first number which can optionally start with an uppercase letter. number = tostring(number) return require(mtext['txt-module-convertnumeric']).spell_number( number, nil, -- fraction numerator nil, -- fraction denominator i == 1 and options.upper, -- true: 'One' instead of 'one' not options.us, -- true: use 'and' between tens/ones etc options.adj, -- true: hyphenated options.ordinal -- true: 'first' instead of 'one' ) or number end local function makeExtra(args, flagCurrent) -- Return extra text that will be inserted before the visible result -- but after any sort key. local extra = args.prefix or '' if mw.ustring.len(extra) > 1 then -- Parameter "~" gives "~3" whereas "over" gives "over 3". if extra:sub(-6, -1) ~= '&nbsp;' then extra = extra .. ' ' end end if flagCurrent then extra = '<span class="currentage"></span>' .. extra end return extra end local function makeSort(value, sortable) -- Return a sort key if requested. -- Assume value is a valid number which has not overflowed. if sortable == 'sortable_table' or sortable == 'sortable_on' or sortable == 'sortable_debug' then local sortKey if value == 0 then sortKey = '5000000000000000000' else local mag = math.floor(math.log10(math.abs(value)) + 1e-14) if value > 0 then sortKey = 7000 + mag else sortKey = 2999 - mag value = value + 10^(mag+1) end sortKey = string.format('%d', sortKey) .. string.format('%015.0f', math.floor(value * 10^(14-mag))) end local result if sortable == 'sortable_table' then result = 'data-sort-value="_SORTKEY_"|' elseif sortable == 'sortable_debug' then result = '<span data-sort-value="_SORTKEY_♠"><span style="border:1px solid">_SORTKEY_♠</span></span>' else result = '<span data-sort-value="_SORTKEY_♠"></span>' end return (result:gsub('_SORTKEY_', sortKey)) end end local translateParameters = { abbr = { off = 'abbr_off', on = 'abbr_on', }, disp = { age = 'disp_age', raw = 'disp_raw', }, format = { raw = 'format_raw', commas = 'format_commas', }, round = { on = 'on', yes = 'on', months = 'ym', weeks = 'ymw', days = 'ymd', hours = 'ymdh', }, sep = { comma = 'sep_comma', [','] = 'sep_comma', serialcomma = 'sep_serialcomma', space = 'sep_space', }, show = { hide = { id = 'hide' }, y = { 'y', id = 'y' }, ym = { 'y', 'm', id = 'ym' }, ymd = { 'y', 'm', 'd', id = 'ymd' }, ymw = { 'y', 'm', 'w', id = 'ymw' }, ymwd = { 'y', 'm', 'w', 'd', id = 'ymwd' }, yd = { 'y', 'd', id = 'yd', keepZero = true }, m = { 'm', id = 'm' }, md = { 'm', 'd', id = 'md' }, w = { 'w', id = 'w' }, wd = { 'w', 'd', id = 'wd' }, h = { 'H', id = 'h' }, hm = { 'H', 'M', id = 'hm' }, hms = { 'H', 'M', 'S', id = 'hms' }, M = { 'M', id = 'M' }, s = { 'S', id = 's' }, d = { 'd', id = 'd' }, dh = { 'd', 'H', id = 'dh' }, dhm = { 'd', 'H', 'M', id = 'dhm' }, dhms = { 'd', 'H', 'M', 'S', id = 'dhms' }, ymdh = { 'y', 'm', 'd', 'H', id = 'ymdh' }, ymdhm = { 'y', 'm', 'd', 'H', 'M', id = 'ymdhm' }, ymwdh = { 'y', 'm', 'w', 'd', 'H', id = 'ymwdh' }, ymwdhm = { 'y', 'm', 'w', 'd', 'H', 'M', id = 'ymwdhm' }, }, sortable = { off = false, on = 'sortable_on', table = 'sortable_table', debug = 'sortable_debug', }, } local spellOptions = { cardinal = {}, Cardinal = { upper = true }, cardinal_us = { us = true }, Cardinal_us = { us = true, upper = true }, ordinal = { ordinal = true }, Ordinal = { ordinal = true, upper = true }, ordinal_us = { ordinal = true, us = true }, Ordinal_us = { ordinal = true, us = true, upper = true }, } local function dateExtract(frame) -- Return part of a date after performing an optional operation. local Date = getExports(frame) local args = frame:getParent().args local parms = {} for i, v in ipairs(args) do parms[i] = v end if yes(args.fix) then table.insert(parms, 'fix') end if yes(args.partial) then table.insert(parms, 'partial') end local show = stripToNil(args.show) or 'dmy' local date = Date(unpack(parms)) if not date then if show == 'format' then return 'error' end return message('mt-need-valid-date') end local add = stripToNil(args.add) if add then for item in add:gmatch('%S+') do date = date + item if not date then return message('mt-cannot-add', item) end end end local sortKey, result local sortable = translateParameters.sortable[args.sortable] if sortable then local value = (date.partial and date.partial.first or date).jdz sortKey = makeSort(value, sortable) end if show ~= 'hide' then result = date[show] if result == nil then result = from_en(date:text(show)) elseif type(result) == 'boolean' then result = result and '1' or '0' else result = from_en(tostring(result)) end end return (sortKey or '') .. makeExtra(args) .. (result or '') end local function rangeJoin(range) -- Return text to be used between a range of ages. return range == 'dash' and '–' or mtext['txt-or'] end local function makeText(values, components, names, options, noUpper) -- Return wikitext representing an age or duration. local text = Collection.new() local count = #values local sep = names.sep or '' for i, v in ipairs(values) do -- v is a number (say 4 for 4 years), or a table ({4,5} for 4 or 5 years). local islist = type(v) == 'table' if (islist or v > 0) or (text.n == 0 and i == count) or (text.n > 0 and components.keepZero) then local fmt, vstr if options.spell then fmt = function(number) return spellNumber(number, options.spell, noUpper or i) end elseif i == 1 and options.format == 'format_commas' then -- Numbers after the first should be small and not need formatting. fmt = formatNumber else fmt = tostring end if islist then vstr = fmt(v[1]) .. rangeJoin(options.range) noUpper = true vstr = vstr .. fmt(v[2]) else vstr = fmt(v) end local name = names[components[i]] if name then if type(name) == 'table' then name = mw.getContentLanguage():plural(islist and v[2] or v, name) end text:add(vstr .. sep .. name) else text:add(vstr) end end end local first, last if options.join == 'sep_space' then first = ' ' last = ' ' elseif options.join == 'sep_comma' then first = ' ' last = ' ' elseif options.join == 'sep_serialcomma' and text.n > 2 then first = ' ' last = mtext['txt-comma-and'] else first = ' ' last = mtext['txt-and'] end for i, v in ipairs(text) do if i < text.n then text[i] = v .. (i + 1 < text.n and first or last) end end local sign = '' if options.isnegative then -- Do not display negative zero. if text.n > 1 or (text.n == 1 and text[1]:sub(1, 1) ~= '0' ) then if options.format == 'format_raw' then sign = '-' -- plain hyphen so result can be used in a calculation else sign = '−' -- Unicode U+2212 MINUS SIGN end end end return (options.sortKey or '') .. (options.extra or '') .. sign .. text:join() .. (options.suffix or '') end local function dateDifference(parms) -- Return a formatted date difference using the given parameters -- which have been validated. local names = { -- Each name is: -- * a string if no plural form of the name is used; or -- * a table of strings, one of which is selected using the rules at -- https://translatewiki.net/wiki/Plural/Mediawiki_plural_rules abbr_off = { sep = '&nbsp;', y = 'ปี', m = 'เดือน', w = 'สัปดาห์', d = 'วัน', H = 'ชั่วโมง', M = 'นาที', S = 'วินาที', }, abbr_on = { y = ' ป.', m = ' ด.', w = ' ส.', d = ' ว.', H = ' ชม.', M = ' น.', S = ' ว.ิ', }, abbr_infant = { -- for {{age for infant}} sep = '&nbsp;', y = {'yr', 'yrs'}, m = {'mo', 'mos'}, w = {'wk', 'wks'}, d = {'day', 'days'}, H = {'hr', 'hrs'}, M = {'min', 'mins'}, S = {'sec', 'secs'}, }, abbr_raw = {}, } local diff = parms.diff -- must be a valid date difference local show = parms.show -- may be nil; default is set below local abbr = parms.abbr or 'abbr_off' local defaultJoin if abbr ~= 'abbr_off' then defaultJoin = 'sep_space' end if not show then show = 'ymd' if parms.disp == 'disp_age' then if diff.years < 3 then defaultJoin = 'sep_space' if diff.years >= 1 then show = 'ym' else show = 'md' end else show = 'y' end end end if type(show) ~= 'table' then show = translateParameters.show[show] end if parms.disp == 'disp_raw' then defaultJoin = 'sep_space' abbr = 'abbr_raw' elseif parms.wantSc then defaultJoin = 'sep_serialcomma' end local diffOptions = { round = parms.round, duration = parms.wantDuration, range = parms.range and true or nil, } local sortKey if parms.sortable then local value = diff.age_days + (parms.wantDuration and 1 or 0) -- days and fraction of a day if diff.isnegative then value = -value end sortKey = makeSort(value, parms.sortable) end local textOptions = { extra = parms.extra, format = parms.format, join = parms.sep or defaultJoin, isnegative = diff.isnegative, range = parms.range, sortKey = sortKey, spell = parms.spell, suffix = parms.suffix, -- not currently used } if show.id == 'hide' then return sortKey or '' end local values = { diff:age(show.id, diffOptions) } if values[1] then return makeText(values, show, names[abbr], textOptions) end if diff.partial then -- Handle a more complex range such as -- {{age_yd|20 Dec 2001|2003|range=yes}} → 1 year, 12 days or 2 years, 11 days local opt = { format = textOptions.format, join = textOptions.join, isnegative = textOptions.isnegative, spell = textOptions.spell, } return (textOptions.sortKey or '') .. makeText({ diff.partial.mindiff:age(show.id, diffOptions) }, show, names[abbr], opt) .. rangeJoin(textOptions.range) .. makeText({ diff.partial.maxdiff:age(show.id, diffOptions) }, show, names[abbr], opt, true) .. (textOptions.suffix or '') end return message('mt-bad-show', show.id) end local function getDates(frame, getopt) -- Parse template parameters and return one of: -- * date (a date table, if single) -- * date1, date2 (two date tables, if not single) -- * text (a string error message) -- A missing date is optionally replaced with the current date. -- If wantMixture is true, a missing date component is replaced -- from the current date, so can get a bizarre mixture of -- specified/current y/m/d as has been done by some "age" templates. -- Some results may be placed in table getopt. local Date, currentDate = getExports(frame) getopt = getopt or {} local function flagCurrent(text) -- This allows the calling template to detect if the current date has been used, -- that is, whether both dates have been entered in a template expecting two. -- For example, an infobox may want the age when an event occurred, not the current age. -- Don't bother detecting if wantMixture is used because not needed and it is a poor option. if not text then if getopt.noMissing then return nil -- this gives a nil date which gives an error end text = 'currentdate' if getopt.flag == 'usesCurrent' then getopt.usesCurrent = true end end return text end local args = frame:getParent().args local fields = {} local isNamed = args.year or args.year1 or args.year2 or args.month or args.month1 or args.month2 or args.day or args.day1 or args.day2 if isNamed then fields[1] = args.year1 or args.year fields[2] = args.month1 or args.month fields[3] = args.day1 or args.day fields[4] = args.year2 fields[5] = args.month2 fields[6] = args.day2 else for i = 1, 6 do fields[i] = args[i] end end local imax = 0 for i = 1, 6 do fields[i] = stripToNil(fields[i]) if fields[i] then imax = i end if getopt.omitZero and i % 3 ~= 1 then -- omit zero months and days as unknown values but keep year 0 which is 1 BCE if isZero(fields[i]) then fields[i] = nil getopt.partial = true end end end local fix = getopt.fix and 'fix' or '' local partialText = getopt.partial and 'partial' or '' local dates = {} if isNamed or imax >= 3 then local nrDates = getopt.single and 1 or 2 if getopt.wantMixture then -- Cannot be partial since empty fields are set from current. local components = { 'year', 'month', 'day' } for i = 1, nrDates * 3 do fields[i] = fields[i] or currentDate[components[i > 3 and i - 3 or i]] end for i = 1, nrDates do local index = i == 1 and 1 or 4 local y, m, d = fields[index], fields[index+1], fields[index+2] if (m == 2 or m == '2') and (d == 29 or d == '29') then -- Workaround error with following which attempt to use invalid date 2001-02-29. -- {{age_ymwd|year1=2001|year2=2004|month2=2|day2=29}} -- {{age_ymwd|year1=2001|month1=2|year2=2004|month2=1|day2=29}} -- TODO Get rid of wantMixture because even this ugly code does not handle -- 'Feb' or 'February' or 'feb' or 'february'. if not ((y % 4 == 0 and y % 100 ~= 0) or y % 400 == 0) then d = 28 end end dates[i] = Date(y, m, d) end else -- If partial dates are allowed, accept -- year only, or -- year and month only -- Do not accept year and day without a month because that makes no sense -- (and because, for example, Date('partial', 2001, nil, 12) sets day = nil, not 12). for i = 1, nrDates do local index = i == 1 and 1 or 4 local y, m, d = fields[index], fields[index+1], fields[index+2] if (getopt.partial and y and (m or not d)) or (y and m and d) then dates[i] = Date(fix, partialText, y, m, d) elseif not y and not m and not d then dates[i] = Date(flagCurrent()) end end end else getopt.textdates = true -- have parsed each date from a single text field dates[1] = Date(fix, partialText, flagCurrent(fields[1])) if not getopt.single then dates[2] = Date(fix, partialText, flagCurrent(fields[2])) end end if not dates[1] then return message(getopt.missing1 or 'mt-need-valid-ymd') end if getopt.single then return dates[1] end if not dates[2] then return message(getopt.missing2 or 'mt-need-valid-ymd2') end return dates[1], dates[2] end local function ageGeneric(frame) -- Return the result required by the specified template. -- Can use sortable=x where x = on/table/off/debug in any supported template. -- Some templates default to sortable=on but can be overridden. local name = frame.args.template if not name then return message('mt-template-x') end local args = frame:getParent().args local specs = { age_days = { -- {{age in days}} show = 'd', disp = 'disp_raw', }, age_days_nts = { -- {{age in days nts}} show = 'd', disp = 'disp_raw', format = 'format_commas', sortable = 'on', }, duration_days = { -- {{duration in days}} show = 'd', disp = 'disp_raw', duration = true, }, duration_days_nts = { -- {{duration in days nts}} show = 'd', disp = 'disp_raw', format = 'format_commas', sortable = 'on', duration = true, }, age_full_years = { -- {{age}} show = 'y', abbr = 'abbr_raw', flag = 'usesCurrent', omitZero = true, range = 'no', }, age_full_years_nts = { -- {{age nts}} show = 'y', abbr = 'abbr_raw', format = 'format_commas', sortable = 'on', }, age_in_years = { -- {{age in years}} show = 'y', abbr = 'abbr_raw', negative = 'error', range = 'dash', }, age_in_years_nts = { -- {{age in years nts}} show = 'y', abbr = 'abbr_raw', negative = 'error', range = 'dash', format = 'format_commas', sortable = 'on', }, age_infant = { -- {{age for infant}} -- Do not set show because special processing is done later. abbr = yes(args.abbr) and 'abbr_infant' or 'abbr_off', disp = 'disp_age', sep = 'sep_space', sortable = 'on', }, age_m = { -- {{age in months}} show = 'm', disp = 'disp_raw', }, age_w = { -- {{age in weeks}} show = 'w', disp = 'disp_raw', }, age_wd = { -- {{age in weeks and days}} show = 'wd', }, age_yd = { -- {{age in years and days}} show = 'yd', format = 'format_commas', sep = args.sep ~= 'and' and 'sep_comma' or nil, }, age_yd_nts = { -- {{age in years and days nts}} show = 'yd', format = 'format_commas', sep = args.sep ~= 'and' and 'sep_comma' or nil, sortable = 'on', }, age_ym = { -- {{age in years and months}} show = 'ym', sep = 'sep_comma', }, age_ymd = { -- {{age in years, months and days}} show = 'ymd', range = true, }, age_ymwd = { -- {{age in years, months, weeks and days}} show = 'ymwd', wantMixture = true, }, } local spec = specs[name] if not spec then return message('mt-template-bad-name') end if name == 'age_days' then local su = stripToNil(args['show unit']) if su then if su == 'abbr' or su == 'full' then spec.disp = nil spec.abbr = su == 'abbr' and 'abbr_on' or nil end end end local partial, autofill local range = stripToNil(args.range) or spec.range if range then -- Suppose partial dates are used and age could be 11 or 12 years. -- "|range=" (empty value) has no effect (spec is used). -- "|range=yes" or spec.range == true sets range = true (gives "11 or 12") -- "|range=dash" or spec.range == 'dash' sets range = 'dash' (gives "11–12"). -- "|range=no" or spec.range == 'no' sets range = nil and fills each date in the diff (gives "12"). -- ("on" is equivalent to "yes", and "off" is equivalent to "no"). -- "|range=OTHER" sets range = nil and rejects partial dates. range = ({ dash = 'dash', off = 'no', no = 'no', [true] = true })[range] or yes(range) if range then partial = true -- accept partial dates with a possible age range for the result if range == 'no' then autofill = true -- missing month/day in first or second date are filled from other date or 1 range = nil end end end local getopt = { fix = yes(args.fix), flag = stripToNil(args.flag) or spec.flag, omitZero = spec.omitZero, partial = partial, wantMixture = spec.wantMixture, } local date1, date2 = getDates(frame, getopt) if type(date1) == 'string' then return date1 end local format = stripToNil(args.format) local spell = spellOptions[format] if format then format = 'format_' .. format elseif name == 'age_days' and getopt.textdates then format = 'format_commas' end local parms = { diff = date2:subtract(date1, { fill = autofill }), wantDuration = spec.duration or yes(args.duration), range = range, wantSc = yes(args.sc), show = args.show == 'hide' and 'hide' or spec.show, abbr = spec.abbr, disp = spec.disp, extra = makeExtra(args, getopt.usesCurrent and format ~= 'format_raw'), format = format or spec.format, round = yes(args.round), sep = spec.sep, sortable = translateParameters.sortable[args.sortable or spec.sortable], spell = spell, } if (spec.negative or frame.args.negative) == 'error' and parms.diff.isnegative then return message('mt-date-wrong-order') end return from_en(dateDifference(parms)) end local function bda(frame) -- Implement [[Template:Birth date and age]]. local args = frame:getParent().args local options = { missing1 = 'mt-need-valid-bd', noMissing = true, single = true, } local date = getDates(frame, options) if type(date) == 'string' then return date -- error text end local Date = getExports(frame) local diff = Date('currentdate') - date if diff.isnegative or diff.years > 150 then return message('mt-invalid-bd-age') end local disp = mtext['txt-bda-disp'] local show = 'y' if diff.years < 2 then disp = 'disp_age' if diff.years == 0 and diff.months == 0 then show = 'd' else show = 'm' end end local result = substituteParameters( mtext['txt-bda'], date:text('%-Y-%m-%d'), from_en(date:text(dateFormat(args))), from_en(dateDifference({ diff = diff, show = show, abbr = 'abbr_off', disp = disp, sep = 'sep_space', })) ) local warnings = tonumber(frame.args.warnings) if warnings and warnings > 0 then local good = { df = true, mf = true, day = true, day1 = true, month = true, month1 = true, year = true, year1 = true, } local invalid local imax = options.textdates and 1 or 3 for k, _ in pairs(args) do if type(k) == 'number' then if k > imax then invalid = tostring(k) break end else if not good[k] then invalid = k break end end end if invalid then result = result .. message('mt-bad-param1', invalid) end end return result end local function dda(frame) -- Implement [[Template:Death date and age]]. local args = frame:getParent().args local options = { missing1 = 'mt-need-valid-dd', missing2 = 'mt-need-valid-bd2', noMissing = true, partial = true, } local date1, date2 = getDates(frame, options) if type(date1) == 'string' then return date1 end local diff = date1 - date2 if diff.isnegative then return message('mt-dd-wrong-order') end local Date = getExports(frame) local today = Date('currentdate') + 1 -- one day in future allows for timezones if date1 > today then return message('mt-dd-future') end local years if diff.partial then years = diff.partial.years years = type(years) == 'table' and years[2] or years else years = diff.years end if years > 150 then return message('mt-invalid-dates-age') end local fmt_date, fmt_ymd if date1.day then -- y, m, d known fmt_date = dateFormat(args) fmt_ymd = '%-Y-%m-%d' elseif date1.month then -- y, m known; d unknown fmt_date = '%B %-Y' fmt_ymd = '%-Y-%m-00' else -- y known; m, d unknown fmt_date = '%-Y' fmt_ymd = '%-Y-00-00' end local sortKey local sortable = translateParameters.sortable[args.sortable] if sortable then local value = (date1.partial and date1.partial.first or date1).jdz sortKey = makeSort(value, sortable) end local result = (sortKey or '') .. substituteParameters( mtext['txt-dda'], date1:text(fmt_ymd), from_en(date1:text(fmt_date)), from_en(dateDifference({ diff = diff, show = 'y', abbr = 'abbr_off', disp = mtext['txt-dda-disp'], range = 'dash', sep = 'sep_space', })) ) local warnings = tonumber(frame.args.warnings) if warnings and warnings > 0 then local good = { df = true, mf = true, } local invalid local imax = options.textdates and 2 or 6 for k, _ in pairs(args) do if type(k) == 'number' then if k > imax then invalid = tostring(k) break end else if not good[k] then invalid = k break end end end if invalid then result = result .. message('mt-bad-param1', invalid) end end return result end local function dateToGsd(frame) -- Implement [[Template:Gregorian serial date]]. -- Return Gregorian serial date of the given date, or the current date. -- The returned value is negative for dates before 1 January 1 AD -- despite the fact that GSD is not defined for such dates. local date = getDates(frame, { wantMixture=true, single=true }) if type(date) == 'string' then return date end return tostring(date.gsd) end local function jdToDate(frame) -- Return formatted date from a Julian date. -- The result includes a time if the input includes a fraction. -- The word 'Julian' is accepted for the Julian calendar. local Date = getExports(frame) local args = frame:getParent().args local date = Date('juliandate', args[1], args[2]) if date then return from_en(date:text()) end return message('mt-need-jdn') end local function dateToJd(frame) -- Return Julian date (a number) from a date which may include a time, -- or the current date ('currentdate') or current date and time ('currentdatetime'). -- The word 'Julian' is accepted for the Julian calendar. local Date = getExports(frame) local args = frame:getParent().args local date = Date(args[1], args[2], args[3], args[4], args[5], args[6], args[7]) if date then return tostring(date.jd) end return message('mt-need-valid-ymd-current') end local function timeInterval(frame) -- Implement [[Template:Time interval]]. -- There are two positional arguments: date1, date2. -- The default for each is the current date and time. -- Result is date2 - date1 formatted. local Date = getExports(frame) local args = frame:getParent().args local parms = { extra = makeExtra(args), wantDuration = yes(args.duration), range = yes(args.range) or (args.range == 'dash' and 'dash' or nil), wantSc = yes(args.sc), } local fix = yes(args.fix) and 'fix' or '' local date1 = Date(fix, 'partial', stripToNil(args[1]) or 'currentdatetime') if not date1 then return message('mt-invalid-start') end local date2 = Date(fix, 'partial', stripToNil(args[2]) or 'currentdatetime') if not date2 then return message('mt-invalid-end') end parms.diff = date2 - date1 for argname, translate in pairs(translateParameters) do local parm = stripToNil(args[argname]) if parm then parm = translate[parm] if parm == nil then -- test for nil because false is a valid setting return message('mt-bad-param2', argname, args[argname]) end parms[argname] = parm end end if parms.round then local round = parms.round local show = parms.show if round ~= 'on' then if show then if show.id ~= round then return message('mt-conflicting-show', args.show, args.round) end else parms.show = translateParameters.show[round] end end parms.round = true end return from_en(dateDifference(parms)) end return { age_generic = ageGeneric, -- can emulate several age templates birth_date_and_age = bda, -- Template:Birth_date_and_age death_date_and_age = dda, -- Template:Death_date_and_age gsd = dateToGsd, -- Template:Gregorian_serial_date extract = dateExtract, -- Template:Extract jd_to_date = jdToDate, -- Template:? JULIANDAY = dateToJd, -- Template:JULIANDAY time_interval = timeInterval, -- Template:Time_interval } 3f3c7d1c84d6ee976af04013cc98283dba46705d อนาวิน สุขเกษมอดิศักดิ์ 0 2 109 60 2023-10-05T13:54:55Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = Anavin Sukkasem-Adisak (2 August 2023).png | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[สภานิติบัญญัติแห่งชาติ|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start1 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | term_end1 = | parliamentarygroup1 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office2 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = 16 พฤษภาคม | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2023|5|16|2023|9|20}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = {{วันเกิด-อายุ|2523|9|5}} | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย f5c764d07c97268145f941de5ce490c74e1d4432 110 109 2023-10-05T14:08:05Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = Anavin Sukkasem-Adisak (2 August 2023).png | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[ศาลรัฐธรรมนูญ|ตุลาการศาลรัฐธรรมนูญ]] | term_start1 = 1 พฤศจิกายน พ.ศ. 2565 | term_end1 = 10 พฤษภาคม พ.ศ. 2566<br>({{อายุปีและวัน|2022|11|1|2023|5|10}}) | office2 = [[สภานิติบัญญัติแห่งชาติ|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start2 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | parliamentarygroup2 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office3 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = 16 พฤษภาคม | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2023|5|16|2023|9|20}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย 4f56b0518ebb739b2565aedb07f9128f565e0115 121 110 2023-10-05T14:54:35Z PeachFullzZ 2 /* งานการเมือง */ wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = Anavin Sukkasem-Adisak (2 August 2023).png | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[ศาลรัฐธรรมนูญ|ตุลาการศาลรัฐธรรมนูญ]] | term_start1 = 1 พฤศจิกายน พ.ศ. 2565 | term_end1 = 10 พฤษภาคม พ.ศ. 2566<br>({{อายุปีและวัน|2022|11|1|2023|5|10}}) | office2 = [[สภานิติบัญญัติแห่งชาติ|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start2 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | parliamentarygroup2 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office3 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = 16 พฤษภาคม | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2023|5|16|2023|9|20}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" <ref>d</ref> === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย == อ้างอิง == {{รายการอ้างอิง}} 0e251a00d689189819f521a7d900864c8d4383ad 122 121 2023-10-05T15:03:59Z PeachFullzZ 2 /* สมาชิกสภานิติบัญญัติแห่งชาติ */ wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = Anavin Sukkasem-Adisak (2 August 2023).png | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[ศาลรัฐธรรมนูญ|ตุลาการศาลรัฐธรรมนูญ]] | term_start1 = 1 พฤศจิกายน พ.ศ. 2565 | term_end1 = 10 พฤษภาคม พ.ศ. 2566<br>({{อายุปีและวัน|2022|11|1|2023|5|10}}) | office2 = [[สภานิติบัญญัติแห่งชาติ|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start2 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | parliamentarygroup2 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office3 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = 16 พฤษภาคม | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2023|5|16|2023|9|20}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" <ref>ไทยเอ็นบีซี [@ThaiNBC]. (3 สิงหาคม 2566). ''[https://twitter.com/ThaiNBC/status/1686795068479590400 ประโยคเด็ด อนาวิน สุขเกษมอดิศักดิ์ ตอบคำถามประชาชน ภายหลังจาก แถลงข่าวเปิดพรรคสมัยใหม่]''. [ทวิต]. ทวิตเตอร์ (X).</ref> === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย == อ้างอิง == {{รายการอ้างอิง}} ede4035258c4e0b8c523176db6f23053d82d10a8 123 122 2023-10-05T15:08:24Z PeachFullzZ 2 /* การเลือกนายกรัฐมนตรีและการลาออก */ wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = Anavin Sukkasem-Adisak (2 August 2023).png | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[ศาลรัฐธรรมนูญ|ตุลาการศาลรัฐธรรมนูญ]] | term_start1 = 1 พฤศจิกายน พ.ศ. 2565 | term_end1 = 10 พฤษภาคม พ.ศ. 2566<br>({{อายุปีและวัน|2022|11|1|2023|5|10}}) | office2 = [[สภานิติบัญญัติแห่งชาติ|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start2 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | parliamentarygroup2 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office3 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = 16 พฤษภาคม | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2023|5|16|2023|9|20}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" <ref>ไทยเอ็นบีซี [@ThaiNBC]. (3 สิงหาคม 2566). ''[https://twitter.com/ThaiNBC/status/1686795068479590400 ประโยคเด็ด อนาวิน สุขเกษมอดิศักดิ์ ตอบคำถามประชาชน ภายหลังจาก แถลงข่าวเปิดพรรคสมัยใหม่]''. [ทวิต]. ทวิตเตอร์ (X).</ref> === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ<ref>เดอะ พีชเชอร์ [@thepeacherco]. (20 กันยายน 2566). ''[https://twitter.com/thepeacherco/status/1704415771441660174 อนาวิน หัวหน้าพรรคสมัยใหม่ โพสต์ลาออกจากตำแหน่ง 'หัวหน้าพรรค' อย่างเป็นทางการ พร้อมทิ้งท้าย "อิอิ"]''. [ทวิต]. ทวิตเตอร์ (X).</ref> ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย == อ้างอิง == {{รายการอ้างอิง}} 64215bbc68208d1a26dc6f84da23a11772c1f8de 124 123 2023-10-05T15:08:59Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = Anavin Sukkasem-Adisak (2 August 2023).png | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[ศาลรัฐธรรมนูญ|ตุลาการศาลรัฐธรรมนูญ]] | term_start1 = 1 พฤศจิกายน พ.ศ. 2565 | term_end1 = 10 พฤษภาคม พ.ศ. 2566<br>({{อายุปีและวัน|2022|11|1|2023|5|10}}) | office2 = [[สภานิติบัญญัติแห่งชาติ|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start2 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | parliamentarygroup2 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office3 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = 16 พฤษภาคม | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2023|5|16|2023|9|20}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" <ref>ไทยเอ็นบีซี [@ThaiNBC]. (3 สิงหาคม 2566). ''[https://twitter.com/ThaiNBC/status/1686795068479590400 ประโยคเด็ด อนาวิน สุขเกษมอดิศักดิ์ ตอบคำถามประชาชน ภายหลังจาก แถลงข่าวเปิดพรรคสมัยใหม่]''. [ทวิต]. ทวิตเตอร์ (X).</ref> === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ<ref>เดอะ พีชเชอร์ [@thepeacherco]. (20 กันยายน 2566). ''[https://twitter.com/thepeacherco/status/1704415771441660174 อนาวิน หัวหน้าพรรคสมัยใหม่ โพสต์ลาออกจากตำแหน่ง 'หัวหน้าพรรค' อย่างเป็นทางการ พร้อมทิ้งท้าย "อิอิ"]''. [ทวิต]. ทวิตเตอร์ (X).</ref> ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย == อ้างอิง == {{รายการอ้างอิง}} 87b9773c67a2e911bbe5f626ae93f3cafd4a3cf3 125 124 2023-10-05T15:17:38Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = Anavin Sukkasem-Adisak (2 August 2023).png | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[ศาลรัฐธรรมนูญ|ตุลาการศาลรัฐธรรมนูญ]] | term_start1 = 1 พฤศจิกายน พ.ศ. 2565 | term_end1 = 10 พฤษภาคม พ.ศ. 2566<br>({{อายุปีและวัน|2022|11|1|2023|5|10}}) | office2 = [[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start2 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | parliamentarygroup2 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office3 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = 16 พฤษภาคม | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2023|5|16|2023|9|20}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" <ref>ไทยเอ็นบีซี [@ThaiNBC]. (3 สิงหาคม 2566). ''[https://twitter.com/ThaiNBC/status/1686795068479590400 ประโยคเด็ด อนาวิน สุขเกษมอดิศักดิ์ ตอบคำถามประชาชน ภายหลังจาก แถลงข่าวเปิดพรรคสมัยใหม่]''. [ทวิต]. ทวิตเตอร์ (X).</ref> === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ<ref>เดอะ พีชเชอร์ [@thepeacherco]. (20 กันยายน 2566). ''[https://twitter.com/thepeacherco/status/1704415771441660174 อนาวิน หัวหน้าพรรคสมัยใหม่ โพสต์ลาออกจากตำแหน่ง 'หัวหน้าพรรค' อย่างเป็นทางการ พร้อมทิ้งท้าย "อิอิ"]''. [ทวิต]. ทวิตเตอร์ (X).</ref> ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย == อ้างอิง == {{รายการอ้างอิง}} 57805c075fdf480181803df2bf25db7324ca9cd9 แม่แบบ:รายการอ้างอิง 10 62 111 2023-10-05T14:14:29Z PeachFullzZ 2 สร้างหน้าด้วย "<templatestyles src="Reflist/styles.css" /><div class="reflist <!-- -->{{#if:{{{1|}}}{{{colwidth|}}}|reflist-columns references-column-width}} <!-- -->{{#switch:{{{liststyle|{{{group|}}}}}}|upper-alpha|upper-roman|lower-alpha|lower-greek|lower-roman=reflist-{{{liststyle|{{{group}}}}}}}} <!-- -->{{#if:{{{1|}}}|{{#iferror:{{#ifexpr: {{{1|1}}} > 1 }}||{{#switch:{{{1|}}}|1=|2=reflist-columns-2|#default=reflist-columns-3}} }}}}" <!-- end class -->{{#if:..." wikitext text/x-wiki <templatestyles src="Reflist/styles.css" /><div class="reflist <!-- -->{{#if:{{{1|}}}{{{colwidth|}}}|reflist-columns references-column-width}} <!-- -->{{#switch:{{{liststyle|{{{group|}}}}}}|upper-alpha|upper-roman|lower-alpha|lower-greek|lower-roman=reflist-{{{liststyle|{{{group}}}}}}}} <!-- -->{{#if:{{{1|}}}|{{#iferror:{{#ifexpr: {{{1|1}}} > 1 }}||{{#switch:{{{1|}}}|1=|2=reflist-columns-2|#default=reflist-columns-3}} }}}}" <!-- end class -->{{#if: {{{1|}}}<!-- start style --> | {{#iferror: {{#ifexpr: {{{1|1}}} > 1 }} |style="column-width: {{{1}}};"}} | {{#if: {{{colwidth|}}}|style="column-width: {{{colwidth}}};"}} }}> {{#tag:references|{{{refs|}}}|group={{{group|}}}|responsive={{#if:{{{1|}}}{{{colwidth|}}}|0|1}}}}</div>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using reflist with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:Reflist]] with unknown parameter "_VALUE_"|ignoreblank=y| 1 | colwidth | group | liststyle | refs }}<noinclude> {{Documentation}} </noinclude> 8c65cc88272db6c0f5cf2b49f84d3e460e60ee5f แม่แบบ:Reflist/styles.css 10 63 112 2023-10-05T14:15:56Z PeachFullzZ 2 สร้างหน้าด้วย "/* {{pp|small=yes}} */ /* can we remove the font size declarations? .references gets a font-size in * common.css that is always 90, and there is nothing else in reflist out in * the wild. May affect column sizes. */ .reflist { font-size: 90%; /* Default font-size */ margin-bottom: 0.5em; list-style-type: decimal; } .reflist .references { font-size: 100%; /* Reset font-size when nested in div.reflist */ margin-bottom: 0;..." sanitized-css text/css /* {{pp|small=yes}} */ /* can we remove the font size declarations? .references gets a font-size in * common.css that is always 90, and there is nothing else in reflist out in * the wild. May affect column sizes. */ .reflist { font-size: 90%; /* Default font-size */ margin-bottom: 0.5em; list-style-type: decimal; } .reflist .references { font-size: 100%; /* Reset font-size when nested in div.reflist */ margin-bottom: 0; /* Avoid double margin when nested in div.reflist */ list-style-type: inherit; /* Enable custom list style types */ } /* columns-2 and columns-3 are legacy for "2 or more" column view from when the * template was implemented with column-count. */ .reflist-columns-2 { column-width: 30em; } .reflist-columns-3 { column-width: 25em; } /* Reset top margin for lists embedded in columns */ .reflist-columns { margin-top: 0.3em; } .reflist-columns ol { margin-top: 0; } /* Avoid elements breaking between columns */ .reflist-columns li { page-break-inside: avoid; /* Removed from CSS in favor of break-inside c. 2020 */ break-inside: avoid-column; } .reflist-upper-alpha { list-style-type: upper-alpha; } .reflist-upper-roman { list-style-type: upper-roman; } .reflist-lower-alpha { list-style-type: lower-alpha; } .reflist-lower-greek { list-style-type: lower-greek; } .reflist-lower-roman { list-style-type: lower-roman; } 531a26d48f0e7826c61f764cfb7d5fb200032c34 113 112 2023-10-05T14:16:11Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Reflist/styles.css]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) sanitized-css text/css /* {{pp|small=yes}} */ /* can we remove the font size declarations? .references gets a font-size in * common.css that is always 90, and there is nothing else in reflist out in * the wild. May affect column sizes. */ .reflist { font-size: 90%; /* Default font-size */ margin-bottom: 0.5em; list-style-type: decimal; } .reflist .references { font-size: 100%; /* Reset font-size when nested in div.reflist */ margin-bottom: 0; /* Avoid double margin when nested in div.reflist */ list-style-type: inherit; /* Enable custom list style types */ } /* columns-2 and columns-3 are legacy for "2 or more" column view from when the * template was implemented with column-count. */ .reflist-columns-2 { column-width: 30em; } .reflist-columns-3 { column-width: 25em; } /* Reset top margin for lists embedded in columns */ .reflist-columns { margin-top: 0.3em; } .reflist-columns ol { margin-top: 0; } /* Avoid elements breaking between columns */ .reflist-columns li { page-break-inside: avoid; /* Removed from CSS in favor of break-inside c. 2020 */ break-inside: avoid-column; } .reflist-upper-alpha { list-style-type: upper-alpha; } .reflist-upper-roman { list-style-type: upper-roman; } .reflist-lower-alpha { list-style-type: lower-alpha; } .reflist-lower-greek { list-style-type: lower-greek; } .reflist-lower-roman { list-style-type: lower-roman; } 531a26d48f0e7826c61f764cfb7d5fb200032c34 แม่แบบ:อ้างอิงทวิต 10 64 114 2023-10-05T14:40:27Z PeachFullzZ 2 สร้างหน้าด้วย "<includeonly>{{#invoke:cite tweet|main}}</includeonly><noinclude>{{documentation}}</noinclude>" wikitext text/x-wiki <includeonly>{{#invoke:cite tweet|main}}</includeonly><noinclude>{{documentation}}</noinclude> 3555ad90e34bdc60b580ea6a043839d27cdb2cad มอดูล:Cite tweet 828 65 115 2023-10-05T14:42:07Z PeachFullzZ 2 สร้างหน้าด้วย "local TwitterSnowflake = require('Module:TwitterSnowflake') local CiteWeb = require('Module:Cite web')[''] local getArgs = require('Module:Arguments').getArgs local p = {} local function _if(arg) return arg and arg ~= '' or nil end p.main = function(frame) local args = getArgs(frame) return p._main(frame, args) end p._main = function(frame, args) local cite_args = { url = 'https://twitter.com/' .. ((args.user and args.number) and (args.u..." Scribunto text/plain local TwitterSnowflake = require('Module:TwitterSnowflake') local CiteWeb = require('Module:Cite web')[''] local getArgs = require('Module:Arguments').getArgs local p = {} local function _if(arg) return arg and arg ~= '' or nil end p.main = function(frame) local args = getArgs(frame) return p._main(frame, args) end p._main = function(frame, args) local cite_args = { url = 'https://twitter.com/' .. ((args.user and args.number) and (args.user .. '/status/' .. args.number) or ''), title = (args.title or ''):gsub('https*://', ''), ['script-title'] = args['script-title'], ['trans-title'] = args['trans-title'], language = args.language, ['author-link'] = args['author-link'] or args.authorlink, others = _if(args.retweet) and ('Retweeted by ' .. args.retweet), via = args.link == 'no' and 'Twitter' or '[[Twitter]]', type = 'Tweet', location = args.location, ['access-date'] = args['access-date'] or args.accessdate, ['archive-date'] = args['archive-date'] or args.archivedate, ['archive-url'] = args['archive-url'] or args.archiveurl, ['url-status'] = args['url-status'] or args['dead-url'] or args.deadurl, quote = args.quote, ref = args.ref, df = args.df, } if _if(args.last1 or args.last) then cite_args.author = (args.last1 or args.last) .. (_if(args.first1 or args.first) and (', ' .. (args.first1 or args.first)) or '') .. ' [@' .. (args.user or '') .. ']' elseif _if(args.author1 or args.author) then cite_args.author = (args.author1 or args.author) .. ' [@' .. (args.user or '') .. ']' elseif _if(args['author-link']) then cite_args.author = args['author-link'] .. ' [@' .. (args.user or '') .. ']' else cite_args.author = '@' .. (args.user or '') end if cite_args.author:find ('[Tt]witter') then cite_args.author = '((' .. cite_args.author .. '))' end if _if(tonumber(args.number)) then cite_args.date = args.date or (_if(args.number) and TwitterSnowflake.snowflakeToDate{ args = {id_str = args.number} }) else cite_args.date = args.date end frame.args = cite_args local output = CiteWeb(frame) -- Error checking local error_template = '<span class="cs1-visible-error citation-comment">%s</span>' local errors = {} if not (_if(args.title) or _if(args['script-title']) or args.user or args.number or args.date) then -- No title; error message is provided by CS1 module. errors[1] = ';' end if not _if(args.user) then errors[1 + #errors] = ' Missing or empty <kbd>&#124;user=</kbd>;' end if not _if(args.number) then errors[1 + #errors] = ' Missing or empty <kbd>&#124;number=</kbd>;' end errors[1 + #errors] = TwitterSnowflake.datecheck{ args = { id_str = args.number or '', date = args.date or '', error1 = ' <kbd>&#124;date=</kbd> mismatches calculated date from <kbd>&#124;number=</kbd> by two or more days;', error2 = ' Missing or empty <kbd>&#124;date=</kbd>, and posted before November 4, 2010;', error3 = ' Invalid <kbd>&#124;number=</kbd> parameter;' }} if errors[1] then local last = errors[#errors] errors[#errors] = last:sub(1, #last - 1) .. ' ([[Template:Cite_tweet#Error_detection|help]])' local error_out = error_template:rep(#errors):format(unpack(errors)) if mw.title.getCurrentTitle():inNamespace(0) then error_out = error_out .. '[[Category:Cite tweet templates with errors]]' end output = output .. error_out end return output end return p 6c05d7dc7f3a626b616bfc089d6f52623082239f มอดูล:Cite web 828 66 116 2023-10-05T14:42:57Z PeachFullzZ 2 สร้างหน้าด้วย "local p = {} local CS1 = require('Module:Citation/CS1') p[''] = function(frame) local newFrame = { getParent = function(self) return frame end, getTitle = function(self) return 'Template:Cite web' end, args = {CitationClass='web'} } setmetatable(newFrame, { __index = function(t, k) if type(frame[k]) == 'function' then return function(...) return frame[k](frame, select(2, ...)) end else..." Scribunto text/plain local p = {} local CS1 = require('Module:Citation/CS1') p[''] = function(frame) local newFrame = { getParent = function(self) return frame end, getTitle = function(self) return 'Template:Cite web' end, args = {CitationClass='web'} } setmetatable(newFrame, { __index = function(t, k) if type(frame[k]) == 'function' then return function(...) return frame[k](frame, select(2, ...)) end else return frame[k] end end }) return CS1.citation(newFrame) end return p fa628191fb961b0afe18fbed767beb959e5797f0 117 116 2023-10-05T14:43:57Z PeachFullzZ 2 Scribunto text/plain local p = {} local CS1 = require('Module:Citation/CS1') p[''] = function(frame) local newFrame = { getParent = function(self) return frame end, getTitle = function(self) return 'แม่แบบ:อ้างอิงเว็บ' end, args = {CitationClass='web'} } setmetatable(newFrame, { __index = function(t, k) if type(frame[k]) == 'function' then return function(...) return frame[k](frame, select(2, ...)) end else return frame[k] end end }) return CS1.citation(newFrame) end return p 2a1de2360c8d19c63744a5f80d36f8445c96309d 118 117 2023-10-05T14:44:11Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Cite web]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local p = {} local CS1 = require('Module:Citation/CS1') p[''] = function(frame) local newFrame = { getParent = function(self) return frame end, getTitle = function(self) return 'แม่แบบ:อ้างอิงเว็บ' end, args = {CitationClass='web'} } setmetatable(newFrame, { __index = function(t, k) if type(frame[k]) == 'function' then return function(...) return frame[k](frame, select(2, ...)) end else return frame[k] end end }) return CS1.citation(newFrame) end return p 2a1de2360c8d19c63744a5f80d36f8445c96309d มอดูล:Citation/CS1 828 67 119 2023-10-05T14:45:01Z PeachFullzZ 2 สร้างหน้าด้วย "require ('strict'); --[[--------------------------< F O R W A R D D E C L A R A T I O N S >-------------------------------------- each of these counts against the Lua upvalue limit ]] local validation; -- functions in Module:Citation/CS1/Date_validation local utilities; -- functions in Module:Citation/CS1/Utilities local z = {}; -- table of tables in Module:Citation/CS1/Utilities local identifier..." Scribunto text/plain require ('strict'); --[[--------------------------< F O R W A R D D E C L A R A T I O N S >-------------------------------------- each of these counts against the Lua upvalue limit ]] local validation; -- functions in Module:Citation/CS1/Date_validation local utilities; -- functions in Module:Citation/CS1/Utilities local z = {}; -- table of tables in Module:Citation/CS1/Utilities local identifiers; -- functions and tables in Module:Citation/CS1/Identifiers local metadata; -- functions in Module:Citation/CS1/COinS local cfg = {}; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration local whitelist = {}; -- table of tables listing valid template parameter names; defined in Module:Citation/CS1/Whitelist --[[------------------< P A G E S C O P E V A R I A B L E S >--------------- declare variables here that have page-wide scope that are not brought in from other modules; that are created here and used here ]] local added_deprecated_cat; -- Boolean flag so that the category is added only once local added_vanc_errs; -- Boolean flag so we only emit one Vancouver error / category local added_generic_name_errs; -- Boolean flag so we only emit one generic name error / category and stop testing names once an error is encountered local Frame; -- holds the module's frame table local is_preview_mode; -- true when article is in preview mode; false when using 'Preview page with this template' (previewing the module) local is_sandbox; -- true when using sandbox modules to render citation --[[--------------------------< F I R S T _ S E T >------------------------------------------------------------ Locates and returns the first set value in a table of values where the order established in the table, left-to-right (or top-to-bottom), is the order in which the values are evaluated. Returns nil if none are set. This version replaces the original 'for _, val in pairs do' and a similar version that used ipairs. With the pairs version the order of evaluation could not be guaranteed. With the ipairs version, a nil value would terminate the for-loop before it reached the actual end of the list. ]] local function first_set (list, count) local i = 1; while i <= count do -- loop through all items in list if utilities.is_set( list[i] ) then return list[i]; -- return the first set list member end i = i + 1; -- point to next end end --[[--------------------------< A D D _ V A N C _ E R R O R >---------------------------------------------------- Adds a single Vancouver system error message to the template's output regardless of how many error actually exist. To prevent duplication, added_vanc_errs is nil until an error message is emitted. added_vanc_errs is a Boolean declared in page scope variables above ]] local function add_vanc_error (source, position) if added_vanc_errs then return end added_vanc_errs = true; -- note that we've added this category utilities.set_message ('err_vancouver', {source, position}); end --[[--------------------------< I S _ S C H E M E >------------------------------------------------------------ does this thing that purports to be a URI scheme seem to be a valid scheme? The scheme is checked to see if it is in agreement with http://tools.ietf.org/html/std66#section-3.1 which says: Scheme names consist of a sequence of characters beginning with a letter and followed by any combination of letters, digits, plus ("+"), period ("."), or hyphen ("-"). returns true if it does, else false ]] local function is_scheme (scheme) return scheme and scheme:match ('^%a[%a%d%+%.%-]*:'); -- true if scheme is set and matches the pattern end --[=[-------------------------< I S _ D O M A I N _ N A M E >-------------------------------------------------- Does this thing that purports to be a domain name seem to be a valid domain name? Syntax defined here: http://tools.ietf.org/html/rfc1034#section-3.5 BNF defined here: https://tools.ietf.org/html/rfc4234 Single character names are generally reserved; see https://tools.ietf.org/html/draft-ietf-dnsind-iana-dns-01#page-15; see also [[Single-letter second-level domain]] list of TLDs: https://www.iana.org/domains/root/db RFC 952 (modified by RFC 1123) requires the first and last character of a hostname to be a letter or a digit. Between the first and last characters the name may use letters, digits, and the hyphen. Also allowed are IPv4 addresses. IPv6 not supported domain is expected to be stripped of any path so that the last character in the last character of the TLD. tld is two or more alpha characters. Any preceding '//' (from splitting a URL with a scheme) will be stripped here. Perhaps not necessary but retained in case it is necessary for IPv4 dot decimal. There are several tests: the first character of the whole domain name including subdomains must be a letter or a digit internationalized domain name (ASCII characters with .xn-- ASCII Compatible Encoding (ACE) prefix xn-- in the TLD) see https://tools.ietf.org/html/rfc3490 single-letter/digit second-level domains in the .org, .cash, and .today TLDs q, x, and z SL domains in the .com TLD i and q SL domains in the .net TLD single-letter SL domains in the ccTLDs (where the ccTLD is two letters) two-character SL domains in gTLDs (where the gTLD is two or more letters) three-plus-character SL domains in gTLDs (where the gTLD is two or more letters) IPv4 dot-decimal address format; TLD not allowed returns true if domain appears to be a proper name and TLD or IPv4 address, else false ]=] local function is_domain_name (domain) if not domain then return false; -- if not set, abandon end domain = domain:gsub ('^//', ''); -- strip '//' from domain name if present; done here so we only have to do it once if not domain:match ('^[%w]') then -- first character must be letter or digit return false; end if domain:match ('^%a+:') then -- hack to detect things that look like s:Page:Title where Page: is namespace at Wikisource return false; end local patterns = { -- patterns that look like URLs '%f[%w][%w][%w%-]+[%w]%.%a%a+$', -- three or more character hostname.hostname or hostname.tld '%f[%w][%w][%w%-]+[%w]%.xn%-%-[%w]+$', -- internationalized domain name with ACE prefix '%f[%a][qxz]%.com$', -- assigned one character .com hostname (x.com times out 2015-12-10) '%f[%a][iq]%.net$', -- assigned one character .net hostname (q.net registered but not active 2015-12-10) '%f[%w][%w]%.%a%a$', -- one character hostname and ccTLD (2 chars) '%f[%w][%w][%w]%.%a%a+$', -- two character hostname and TLD '^%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?', -- IPv4 address } for _, pattern in ipairs (patterns) do -- loop through the patterns list if domain:match (pattern) then return true; -- if a match then we think that this thing that purports to be a URL is a URL end end for _, d in ipairs (cfg.single_letter_2nd_lvl_domains_t) do -- look for single letter second level domain names for these top level domains if domain:match ('%f[%w][%w]%.' .. d) then return true end end return false; -- no matches, we don't know what this thing is end --[[--------------------------< I S _ U R L >------------------------------------------------------------------ returns true if the scheme and domain parts of a URL appear to be a valid URL; else false. This function is the last step in the validation process. This function is separate because there are cases that are not covered by split_url(), for example is_parameter_ext_wikilink() which is looking for bracketted external wikilinks. ]] local function is_url (scheme, domain) if utilities.is_set (scheme) then -- if scheme is set check it and domain return is_scheme (scheme) and is_domain_name (domain); else return is_domain_name (domain); -- scheme not set when URL is protocol-relative end end --[[--------------------------< S P L I T _ U R L >------------------------------------------------------------ Split a URL into a scheme, authority indicator, and domain. First remove Fully Qualified Domain Name terminator (a dot following TLD) (if any) and any path(/), query(?) or fragment(#). If protocol-relative URL, return nil scheme and domain else return nil for both scheme and domain. When not protocol-relative, get scheme, authority indicator, and domain. If there is an authority indicator (one or more '/' characters immediately following the scheme's colon), make sure that there are only 2. Any URL that does not have news: scheme must have authority indicator (//). TODO: are there other common schemes like news: that don't use authority indicator? Strip off any port and path; ]] local function split_url (url_str) local scheme, authority, domain; url_str = url_str:gsub ('([%a%d])%.?[/%?#].*$', '%1'); -- strip FQDN terminator and path(/), query(?), fragment (#) (the capture prevents false replacement of '//') if url_str:match ('^//%S*') then -- if there is what appears to be a protocol-relative URL domain = url_str:match ('^//(%S*)') elseif url_str:match ('%S-:/*%S+') then -- if there is what appears to be a scheme, optional authority indicator, and domain name scheme, authority, domain = url_str:match ('(%S-:)(/*)(%S+)'); -- extract the scheme, authority indicator, and domain portions if utilities.is_set (authority) then authority = authority:gsub ('//', '', 1); -- replace place 1 pair of '/' with nothing; if utilities.is_set(authority) then -- if anything left (1 or 3+ '/' where authority should be) then return scheme; -- return scheme only making domain nil which will cause an error message end else if not scheme:match ('^news:') then -- except for news:..., MediaWiki won't link URLs that do not have authority indicator; TODO: a better way to do this test? return scheme; -- return scheme only making domain nil which will cause an error message end end domain = domain:gsub ('(%a):%d+', '%1'); -- strip port number if present end return scheme, domain; end --[[--------------------------< L I N K _ P A R A M _ O K >--------------------------------------------------- checks the content of |title-link=, |series-link=, |author-link=, etc. for properly formatted content: no wikilinks, no URLs Link parameters are to hold the title of a Wikipedia article, so none of the WP:TITLESPECIALCHARACTERS are allowed: # < > [ ] | { } _ except the underscore which is used as a space in wiki URLs and # which is used for section links returns false when the value contains any of these characters. When there are no illegal characters, this function returns TRUE if value DOES NOT appear to be a valid URL (the |<param>-link= parameter is ok); else false when value appears to be a valid URL (the |<param>-link= parameter is NOT ok). ]] local function link_param_ok (value) local scheme, domain; if value:find ('[<>%[%]|{}]') then -- if any prohibited characters return false; end scheme, domain = split_url (value); -- get scheme or nil and domain or nil from URL; return not is_url (scheme, domain); -- return true if value DOES NOT appear to be a valid URL end --[[--------------------------< L I N K _ T I T L E _ O K >--------------------------------------------------- Use link_param_ok() to validate |<param>-link= value and its matching |<title>= value. |<title>= may be wiki-linked but not when |<param>-link= has a value. This function emits an error message when that condition exists check <link> for inter-language interwiki-link prefix. prefix must be a MediaWiki-recognized language code and must begin with a colon. ]] local function link_title_ok (link, lorig, title, torig) local orig; if utilities.is_set (link) then -- don't bother if <param>-link doesn't have a value if not link_param_ok (link) then -- check |<param>-link= markup orig = lorig; -- identify the failing link parameter elseif title:find ('%[%[') then -- check |title= for wikilink markup orig = torig; -- identify the failing |title= parameter elseif link:match ('^%a+:') then -- if the link is what looks like an interwiki local prefix = link:match ('^(%a+):'):lower(); -- get the interwiki prefix if cfg.inter_wiki_map[prefix] then -- if prefix is in the map, must have preceding colon orig = lorig; -- flag as error end end end if utilities.is_set (orig) then link = ''; -- unset utilities.set_message ('err_bad_paramlink', orig); -- URL or wikilink in |title= with |title-link=; end return link; -- link if ok, empty string else end --[[--------------------------< C H E C K _ U R L >------------------------------------------------------------ Determines whether a URL string appears to be valid. First we test for space characters. If any are found, return false. Then split the URL into scheme and domain portions, or for protocol-relative (//example.com) URLs, just the domain. Use is_url() to validate the two portions of the URL. If both are valid, or for protocol-relative if domain is valid, return true, else false. Because it is different from a standard URL, and because this module used external_link() to make external links that work for standard and news: links, we validate newsgroup names here. The specification for a newsgroup name is at https://tools.ietf.org/html/rfc5536#section-3.1.4 ]] local function check_url( url_str ) if nil == url_str:match ("^%S+$") then -- if there are any spaces in |url=value it can't be a proper URL return false; end local scheme, domain; scheme, domain = split_url (url_str); -- get scheme or nil and domain or nil from URL; if 'news:' == scheme then -- special case for newsgroups return domain:match('^[%a%d%+%-_]+%.[%a%d%+%-_%.]*[%a%d%+%-_]$'); end return is_url (scheme, domain); -- return true if value appears to be a valid URL end --[=[-------------------------< I S _ P A R A M E T E R _ E X T _ W I K I L I N K >---------------------------- Return true if a parameter value has a string that begins and ends with square brackets [ and ] and the first non-space characters following the opening bracket appear to be a URL. The test will also find external wikilinks that use protocol-relative URLs. Also finds bare URLs. The frontier pattern prevents a match on interwiki-links which are similar to scheme:path URLs. The tests that find bracketed URLs are required because the parameters that call this test (currently |title=, |chapter=, |work=, and |publisher=) may have wikilinks and there are articles or redirects like '//Hus' so, while uncommon, |title=[[//Hus]] is possible as might be [[en://Hus]]. ]=] local function is_parameter_ext_wikilink (value) local scheme, domain; if value:match ('%f[%[]%[%a%S*:%S+.*%]') then -- if ext. wikilink with scheme and domain: [xxxx://yyyyy.zzz] scheme, domain = split_url (value:match ('%f[%[]%[(%a%S*:%S+).*%]')); elseif value:match ('%f[%[]%[//%S+.*%]') then -- if protocol-relative ext. wikilink: [//yyyyy.zzz] scheme, domain = split_url (value:match ('%f[%[]%[(//%S+).*%]')); elseif value:match ('%a%S*:%S+') then -- if bare URL with scheme; may have leading or trailing plain text scheme, domain = split_url (value:match ('(%a%S*:%S+)')); elseif value:match ('//%S+') then -- if protocol-relative bare URL: //yyyyy.zzz; may have leading or trailing plain text scheme, domain = split_url (value:match ('(//%S+)')); -- what is left should be the domain else return false; -- didn't find anything that is obviously a URL end return is_url (scheme, domain); -- return true if value appears to be a valid URL end --[[-------------------------< C H E C K _ F O R _ U R L >----------------------------------------------------- loop through a list of parameters and their values. Look at the value and if it has an external link, emit an error message. ]] local function check_for_url (parameter_list, error_list) for k, v in pairs (parameter_list) do -- for each parameter in the list if is_parameter_ext_wikilink (v) then -- look at the value; if there is a URL add an error message table.insert (error_list, utilities.wrap_style ('parameter', k)); end end end --[[--------------------------< S A F E _ F O R _ U R L >------------------------------------------------------ Escape sequences for content that will be used for URL descriptions ]] local function safe_for_url( str ) if str:match( "%[%[.-%]%]" ) ~= nil then utilities.set_message ('err_wikilink_in_url', {}); end return str:gsub( '[%[%]\n]', { ['['] = '&#91;', [']'] = '&#93;', ['\n'] = ' ' } ); end --[[--------------------------< E X T E R N A L _ L I N K >---------------------------------------------------- Format an external link with error checking ]] local function external_link (URL, label, source, access) local err_msg = ''; local domain; local path; local base_url; if not utilities.is_set (label) then label = URL; if utilities.is_set (source) then utilities.set_message ('err_bare_url_missing_title', {utilities.wrap_style ('parameter', source)}); else error (cfg.messages["bare_url_no_origin"]); -- programmer error; valid parameter name does not have matching meta-parameter end end if not check_url (URL) then utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); end domain, path = URL:match ('^([/%.%-%+:%a%d]+)([/%?#].*)$'); -- split the URL into scheme plus domain and path if path then -- if there is a path portion path = path:gsub ('[%[%]]', {['['] = '%5b', [']'] = '%5d'}); -- replace '[' and ']' with their percent-encoded values URL = table.concat ({domain, path}); -- and reassemble end base_url = table.concat ({ "[", URL, " ", safe_for_url (label), "]" }); -- assemble a wiki-markup URL if utilities.is_set (access) then -- access level (subscription, registration, limited) base_url = utilities.substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[access].class, cfg.presentation[access].title, base_url}); -- add the appropriate icon end return base_url; end --[[--------------------------< D E P R E C A T E D _ P A R A M E T E R >-------------------------------------- Categorize and emit an error message when the citation contains one or more deprecated parameters. The function includes the offending parameter name to the error message. Only one error message is emitted regardless of the number of deprecated parameters in the citation. added_deprecated_cat is a Boolean declared in page scope variables above ]] local function deprecated_parameter(name) if not added_deprecated_cat then added_deprecated_cat = true; -- note that we've added this category utilities.set_message ('err_deprecated_params', {name}); -- add error message end end --[=[-------------------------< K E R N _ Q U O T E S >-------------------------------------------------------- Apply kerning to open the space between the quote mark provided by the module and a leading or trailing quote mark contained in a |title= or |chapter= parameter's value. This function will positive kern either single or double quotes: "'Unkerned title with leading and trailing single quote marks'" " 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example) Double single quotes (italic or bold wiki-markup) are not kerned. Replaces Unicode quote marks in plain text or in the label portion of a [[L|D]] style wikilink with typewriter quote marks regardless of the need for kerning. Unicode quote marks are not replaced in simple [[D]] wikilinks. Call this function for chapter titles, for website titles, etc.; not for book titles. ]=] local function kern_quotes (str) local cap = ''; local wl_type, label, link; wl_type, label, link = utilities.is_wikilink (str); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]] if 1 == wl_type then -- [[D]] simple wikilink with or without quote marks if mw.ustring.match (str, '%[%[[\"“”\'‘’].+[\"“”\'‘’]%]%]') then -- leading and trailing quote marks str = utilities.substitute (cfg.presentation['kern-left'], str); str = utilities.substitute (cfg.presentation['kern-right'], str); elseif mw.ustring.match (str, '%[%[[\"“”\'‘’].+%]%]') then -- leading quote marks str = utilities.substitute (cfg.presentation['kern-left'], str); elseif mw.ustring.match (str, '%[%[.+[\"“”\'‘’]%]%]') then -- trailing quote marks str = utilities.substitute (cfg.presentation['kern-right'], str); end else -- plain text or [[L|D]]; text in label variable label = mw.ustring.gsub (label, '[“”]', '\"'); -- replace “” (U+201C & U+201D) with " (typewriter double quote mark) label = mw.ustring.gsub (label, '[‘’]', '\''); -- replace ‘’ (U+2018 & U+2019) with ' (typewriter single quote mark) cap = mw.ustring.match (label, "^([\"\'][^\'].+)"); -- match leading double or single quote but not doubled single quotes (italic markup) if utilities.is_set (cap) then label = utilities.substitute (cfg.presentation['kern-left'], cap); end cap = mw.ustring.match (label, "^(.+[^\'][\"\'])$") -- match trailing double or single quote but not doubled single quotes (italic markup) if utilities.is_set (cap) then label = utilities.substitute (cfg.presentation['kern-right'], cap); end if 2 == wl_type then str = utilities.make_wikilink (link, label); -- reassemble the wikilink else str = label; end end return str; end --[[--------------------------< F O R M A T _ S C R I P T _ V A L U E >---------------------------------------- |script-title= holds title parameters that are not written in Latin-based scripts: Chinese, Japanese, Arabic, Hebrew, etc. These scripts should not be italicized and may be written right-to-left. The value supplied by |script-title= is concatenated onto Title after Title has been wrapped in italic markup. Regardless of language, all values provided by |script-title= are wrapped in <bdi>...</bdi> tags to isolate RTL languages from the English left to right. |script-title= provides a unique feature. The value in |script-title= may be prefixed with a two-character ISO 639-1 language code and a colon: |script-title=ja:*** *** (where * represents a Japanese character) Spaces between the two-character code and the colon and the colon and the first script character are allowed: |script-title=ja : *** *** |script-title=ja: *** *** |script-title=ja :*** *** Spaces preceding the prefix are allowed: |script-title = ja:*** *** The prefix is checked for validity. If it is a valid ISO 639-1 language code, the lang attribute (lang="ja") is added to the <bdi> tag so that browsers can know the language the tag contains. This may help the browser render the script more correctly. If the prefix is invalid, the lang attribute is not added. At this time there is no error message for this condition. Supports |script-title=, |script-chapter=, |script-<periodical>= ]] local function format_script_value (script_value, script_param) local lang=''; -- initialize to empty string local name; if script_value:match('^%l%l%l?%s*:') then -- if first 3 or 4 non-space characters are script language prefix lang = script_value:match('^(%l%l%l?)%s*:%s*%S.*'); -- get the language prefix or nil if there is no script if not utilities.is_set (lang) then utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing title part']}); -- prefix without 'title'; add error message return ''; -- script_value was just the prefix so return empty string end -- if we get this far we have prefix and script name = cfg.lang_tag_remap[lang] or mw.language.fetchLanguageName( lang, cfg.this_wiki_code ); -- get language name so that we can use it to categorize if utilities.is_set (name) then -- is prefix a proper ISO 639-1 language code? script_value = script_value:gsub ('^%l+%s*:%s*', ''); -- strip prefix from script -- is prefix one of these language codes? if utilities.in_array (lang, cfg.script_lang_codes) then utilities.add_prop_cat ('script', {name, lang}) else utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['unknown language code']}); -- unknown script-language; add error message end lang = ' lang="' .. lang .. '" '; -- convert prefix into a lang attribute else utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['invalid language code']}); -- invalid language code; add error message lang = ''; -- invalid so set lang to empty string end else utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing prefix']}); -- no language code prefix; add error message end script_value = utilities.substitute (cfg.presentation['bdi'], {lang, script_value}); -- isolate in case script is RTL return script_value; end --[[--------------------------< S C R I P T _ C O N C A T E N A T E >------------------------------------------ Initially for |title= and |script-title=, this function concatenates those two parameter values after the script value has been wrapped in <bdi> tags. ]] local function script_concatenate (title, script, script_param) if utilities.is_set (script) then script = format_script_value (script, script_param); -- <bdi> tags, lang attribute, categorization, etc.; returns empty string on error if utilities.is_set (script) then title = title .. ' ' .. script; -- concatenate title and script title end end return title; end --[[--------------------------< W R A P _ M S G >-------------------------------------------------------------- Applies additional message text to various parameter values. Supplied string is wrapped using a message_list configuration taking one argument. Supports lower case text for {{citation}} templates. Additional text taken from citation_config.messages - the reason this function is similar to but separate from wrap_style(). ]] local function wrap_msg (key, str, lower) if not utilities.is_set ( str ) then return ""; end if true == lower then local msg; msg = cfg.messages[key]:lower(); -- set the message to lower case before return utilities.substitute ( msg, str ); -- including template text else return utilities.substitute ( cfg.messages[key], str ); end end --[[----------------< W I K I S O U R C E _ U R L _ M A K E >------------------- Makes a Wikisource URL from Wikisource interwiki-link. Returns the URL and appropriate label; nil else. str is the value assigned to |chapter= (or aliases) or |title= or |title-link= ]] local function wikisource_url_make (str) local wl_type, D, L; local ws_url, ws_label; local wikisource_prefix = table.concat ({'https://', cfg.this_wiki_code, '.wikisource.org/wiki/'}); wl_type, D, L = utilities.is_wikilink (str); -- wl_type is 0 (not a wikilink), 1 (simple wikilink), 2 (complex wikilink) if 0 == wl_type then -- not a wikilink; might be from |title-link= str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace if utilities.is_set (str) then ws_url = table.concat ({ -- build a Wikisource URL wikisource_prefix, -- prefix str, -- article title }); ws_label = str; -- label for the URL end elseif 1 == wl_type then -- simple wikilink: [[Wikisource:ws article]] str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace if utilities.is_set (str) then ws_url = table.concat ({ -- build a Wikisource URL wikisource_prefix, -- prefix str, -- article title }); ws_label = str; -- label for the URL end elseif 2 == wl_type then -- non-so-simple wikilink: [[Wikisource:ws article|displayed text]] ([[L|D]]) str = L:match ('^[Ww]ikisource:(.+)') or L:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace if utilities.is_set (str) then ws_label = D; -- get ws article name from display portion of interwiki link ws_url = table.concat ({ -- build a Wikisource URL wikisource_prefix, -- prefix str, -- article title without namespace from link portion of wikilink }); end end if ws_url then ws_url = mw.uri.encode (ws_url, 'WIKI'); -- make a usable URL ws_url = ws_url:gsub ('%%23', '#'); -- undo percent-encoding of fragment marker end return ws_url, ws_label, L or D; -- return proper URL or nil and a label or nil end --[[----------------< F O R M A T _ P E R I O D I C A L >----------------------- Format the three periodical parameters: |script-<periodical>=, |<periodical>=, and |trans-<periodical>= into a single Periodical meta-parameter. ]] local function format_periodical (script_periodical, script_periodical_source, periodical, trans_periodical) if not utilities.is_set (periodical) then periodical = ''; -- to be safe for concatenation else periodical = utilities.wrap_style ('italic-title', periodical); -- style end periodical = script_concatenate (periodical, script_periodical, script_periodical_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped if utilities.is_set (trans_periodical) then trans_periodical = utilities.wrap_style ('trans-italic-title', trans_periodical); if utilities.is_set (periodical) then periodical = periodical .. ' ' .. trans_periodical; else -- here when trans-periodical without periodical or script-periodical periodical = trans_periodical; utilities.set_message ('err_trans_missing_title', {'periodical'}); end end return periodical; end --[[------------------< F O R M A T _ C H A P T E R _ T I T L E >--------------- Format the four chapter parameters: |script-chapter=, |chapter=, |trans-chapter=, and |chapter-url= into a single chapter meta- parameter (chapter_url_source used for error messages). ]] local function format_chapter_title (script_chapter, script_chapter_source, chapter, chapter_source, trans_chapter, trans_chapter_source, chapter_url, chapter_url_source, no_quotes, access) local ws_url, ws_label, L = wikisource_url_make (chapter); -- make a wikisource URL and label from a wikisource interwiki link if ws_url then ws_label = ws_label:gsub ('_', ' '); -- replace underscore separators with space characters chapter = ws_label; end if not utilities.is_set (chapter) then chapter = ''; -- to be safe for concatenation else if false == no_quotes then chapter = kern_quotes (chapter); -- if necessary, separate chapter title's leading and trailing quote marks from module provided quote marks chapter = utilities.wrap_style ('quoted-title', chapter); end end chapter = script_concatenate (chapter, script_chapter, script_chapter_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped if utilities.is_set (chapter_url) then chapter = external_link (chapter_url, chapter, chapter_url_source, access); -- adds bare_url_missing_title error if appropriate elseif ws_url then chapter = external_link (ws_url, chapter .. '&nbsp;', 'ws link in chapter'); -- adds bare_url_missing_title error if appropriate; space char to move icon away from chap text; TODO: better way to do this? chapter = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, chapter}); end if utilities.is_set (trans_chapter) then trans_chapter = utilities.wrap_style ('trans-quoted-title', trans_chapter); if utilities.is_set (chapter) then chapter = chapter .. ' ' .. trans_chapter; else -- here when trans_chapter without chapter or script-chapter chapter = trans_chapter; chapter_source = trans_chapter_source:match ('trans%-?(.+)'); -- when no chapter, get matching name from trans-<param> utilities.set_message ('err_trans_missing_title', {chapter_source}); end end return chapter; end --[[----------------< H A S _ I N V I S I B L E _ C H A R S >------------------- This function searches a parameter's value for non-printable or invisible characters. The search stops at the first match. This function will detect the visible replacement character when it is part of the Wikisource. Detects but ignores nowiki and math stripmarkers. Also detects other named stripmarkers (gallery, math, pre, ref) and identifies them with a slightly different error message. See also coins_cleanup(). Output of this function is an error message that identifies the character or the Unicode group, or the stripmarker that was detected along with its position (or, for multi-byte characters, the position of its first byte) in the parameter value. ]] local function has_invisible_chars (param, v) local position = ''; -- position of invisible char or starting position of stripmarker local capture; -- used by stripmarker detection to hold name of the stripmarker local stripmarker; -- boolean set true when a stripmarker is found capture = string.match (v, '[%w%p ]*'); -- test for values that are simple ASCII text and bypass other tests if true if capture == v then -- if same there are no Unicode characters return; end for _, invisible_char in ipairs (cfg.invisible_chars) do local char_name = invisible_char[1]; -- the character or group name local pattern = invisible_char[2]; -- the pattern used to find it position, _, capture = mw.ustring.find (v, pattern); -- see if the parameter value contains characters that match the pattern if position and (cfg.invisible_defs.zwj == capture) then -- if we found a zero-width joiner character if mw.ustring.find (v, cfg.indic_script) then -- it's ok if one of the Indic scripts position = nil; -- unset position elseif cfg.emoji_t[mw.ustring.codepoint (v, position+1)] then -- is zwj followed by a character listed in emoji{}? position = nil; -- unset position end end if position then if 'nowiki' == capture or 'math' == capture or -- nowiki and math stripmarkers (not an error condition) ('templatestyles' == capture and utilities.in_array (param, {'id', 'quote'})) then -- templatestyles stripmarker allowed in these parameters stripmarker = true; -- set a flag elseif true == stripmarker and cfg.invisible_defs.del == capture then -- because stripmakers begin and end with the delete char, assume that we've found one end of a stripmarker position = nil; -- unset else local err_msg; if capture and not (cfg.invisible_defs.del == capture or cfg.invisible_defs.zwj == capture) then err_msg = capture .. ' ' .. char_name; else err_msg = char_name .. ' ' .. 'character'; end utilities.set_message ('err_invisible_char', {err_msg, utilities.wrap_style ('parameter', param), position}); -- add error message return; -- and done with this parameter end end end end --[[-------------------< A R G U M E N T _ W R A P P E R >---------------------- Argument wrapper. This function provides support for argument mapping defined in the configuration file so that multiple names can be transparently aliased to single internal variable. ]] local function argument_wrapper ( args ) local origin = {}; return setmetatable({ ORIGIN = function ( self, k ) local dummy = self[k]; -- force the variable to be loaded. return origin[k]; end }, { __index = function ( tbl, k ) if origin[k] ~= nil then return nil; end local args, list, v = args, cfg.aliases[k]; if type( list ) == 'table' then v, origin[k] = utilities.select_one ( args, list, 'err_redundant_parameters' ); if origin[k] == nil then origin[k] = ''; -- Empty string, not nil end elseif list ~= nil then v, origin[k] = args[list], list; else -- maybe let through instead of raising an error? -- v, origin[k] = args[k], k; error( cfg.messages['unknown_argument_map'] .. ': ' .. k); end -- Empty strings, not nil; if v == nil then v = ''; origin[k] = ''; end tbl = rawset( tbl, k, v ); return v; end, }); end --[[--------------------------< N O W R A P _ D A T E >------------------------- When date is YYYY-MM-DD format wrap in nowrap span: <span ...>YYYY-MM-DD</span>. When date is DD MMMM YYYY or is MMMM DD, YYYY then wrap in nowrap span: <span ...>DD MMMM</span> YYYY or <span ...>MMMM DD,</span> YYYY DOES NOT yet support MMMM YYYY or any of the date ranges. ]] local function nowrap_date (date) local cap = ''; local cap2 = ''; if date:match("^%d%d%d%d%-%d%d%-%d%d$") then date = utilities.substitute (cfg.presentation['nowrap1'], date); elseif date:match("^%a+%s*%d%d?,%s+%d%d%d%d$") or date:match ("^%d%d?%s*%a+%s+%d%d%d%d$") then cap, cap2 = string.match (date, "^(.*)%s+(%d%d%d%d)$"); date = utilities.substitute (cfg.presentation['nowrap2'], {cap, cap2}); end return date; end --[[--------------------------< S E T _ T I T L E T Y P E >--------------------- This function sets default title types (equivalent to the citation including |type=<default value>) for those templates that have defaults. Also handles the special case where it is desirable to omit the title type from the rendered citation (|type=none). ]] local function set_titletype (cite_class, title_type) if utilities.is_set (title_type) then if 'none' == cfg.keywords_xlate[title_type] then title_type = ''; -- if |type=none then type parameter not displayed end return title_type; -- if |type= has been set to any other value use that value end return cfg.title_types [cite_class] or ''; -- set template's default title type; else empty string for concatenation end --[[--------------------------< S A F E _ J O I N >----------------------------- Joins a sequence of strings together while checking for duplicate separation characters. ]] local function safe_join( tbl, duplicate_char ) local f = {}; -- create a function table appropriate to type of 'duplicate character' if 1 == #duplicate_char then -- for single byte ASCII characters use the string library functions f.gsub = string.gsub f.match = string.match f.sub = string.sub else -- for multi-byte characters use the ustring library functions f.gsub = mw.ustring.gsub f.match = mw.ustring.match f.sub = mw.ustring.sub end local str = ''; -- the output string local comp = ''; -- what does 'comp' mean? local end_chr = ''; local trim; for _, value in ipairs( tbl ) do if value == nil then value = ''; end if str == '' then -- if output string is empty str = value; -- assign value to it (first time through the loop) elseif value ~= '' then if value:sub(1, 1) == '<' then -- special case of values enclosed in spans and other markup. comp = value:gsub( "%b<>", "" ); -- remove HTML markup (<span>string</span> -> string) else comp = value; end -- typically duplicate_char is sepc if f.sub(comp, 1, 1) == duplicate_char then -- is first character same as duplicate_char? why test first character? -- Because individual string segments often (always?) begin with terminal punct for the -- preceding segment: 'First element' .. 'sepc next element' .. etc.? trim = false; end_chr = f.sub(str, -1, -1); -- get the last character of the output string -- str = str .. "<HERE(enchr=" .. end_chr .. ")" -- debug stuff? if end_chr == duplicate_char then -- if same as separator str = f.sub(str, 1, -2); -- remove it elseif end_chr == "'" then -- if it might be wiki-markup if f.sub(str, -3, -1) == duplicate_char .. "''" then -- if last three chars of str are sepc'' str = f.sub(str, 1, -4) .. "''"; -- remove them and add back '' elseif f.sub(str, -5, -1) == duplicate_char .. "]]''" then -- if last five chars of str are sepc]]'' trim = true; -- why? why do this and next differently from previous? elseif f.sub(str, -4, -1) == duplicate_char .. "]''" then -- if last four chars of str are sepc]'' trim = true; -- same question end elseif end_chr == "]" then -- if it might be wiki-markup if f.sub(str, -3, -1) == duplicate_char .. "]]" then -- if last three chars of str are sepc]] wikilink trim = true; elseif f.sub(str, -3, -1) == duplicate_char .. '"]' then -- if last three chars of str are sepc"] quoted external link trim = true; elseif f.sub(str, -2, -1) == duplicate_char .. "]" then -- if last two chars of str are sepc] external link trim = true; elseif f.sub(str, -4, -1) == duplicate_char .. "'']" then -- normal case when |url=something & |title=Title. trim = true; end elseif end_chr == " " then -- if last char of output string is a space if f.sub(str, -2, -1) == duplicate_char .. " " then -- if last two chars of str are <sepc><space> str = f.sub(str, 1, -3); -- remove them both end end if trim then if value ~= comp then -- value does not equal comp when value contains HTML markup local dup2 = duplicate_char; if f.match(dup2, "%A" ) then dup2 = "%" .. dup2; end -- if duplicate_char not a letter then escape it value = f.gsub(value, "(%b<>)" .. dup2, "%1", 1 ) -- remove duplicate_char if it follows HTML markup else value = f.sub(value, 2, -1 ); -- remove duplicate_char when it is first character end end end str = str .. value; -- add it to the output string end end return str; end --[[--------------------------< I S _ S U F F I X >----------------------------- returns true if suffix is properly formed Jr, Sr, or ordinal in the range 1–9. Puncutation not allowed. ]] local function is_suffix (suffix) if utilities.in_array (suffix, {'Jr', 'Sr', 'Jnr', 'Snr', '1st', '2nd', '3rd'}) or suffix:match ('^%dth$') then return true; end return false; end --[[--------------------< I S _ G O O D _ V A N C _ N A M E >------------------- For Vancouver style, author/editor names are supposed to be rendered in Latin (read ASCII) characters. When a name uses characters that contain diacritical marks, those characters are to be converted to the corresponding Latin character. When a name is written using a non-Latin alphabet or logogram, that name is to be transliterated into Latin characters. The module doesn't do this so editors may/must. This test allows |first= and |last= names to contain any of the letters defined in the four Unicode Latin character sets [http://www.unicode.org/charts/PDF/U0000.pdf C0 Controls and Basic Latin] 0041–005A, 0061–007A [http://www.unicode.org/charts/PDF/U0080.pdf C1 Controls and Latin-1 Supplement] 00C0–00D6, 00D8–00F6, 00F8–00FF [http://www.unicode.org/charts/PDF/U0100.pdf Latin Extended-A] 0100–017F [http://www.unicode.org/charts/PDF/U0180.pdf Latin Extended-B] 0180–01BF, 01C4–024F |lastn= also allowed to contain hyphens, spaces, and apostrophes. (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/) |firstn= also allowed to contain hyphens, spaces, apostrophes, and periods This original test: if nil == mw.ustring.find (last, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%']*$") or nil == mw.ustring.find (first, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%'%.]+[2-6%a]*$") then was written outside of the code editor and pasted here because the code editor gets confused between character insertion point and cursor position. The test has been rewritten to use decimal character escape sequence for the individual bytes of the Unicode characters so that it is not necessary to use an external editor to maintain this code. \195\128-\195\150 – À-Ö (U+00C0–U+00D6 – C0 controls) \195\152-\195\182 – Ø-ö (U+00D8-U+00F6 – C0 controls) \195\184-\198\191 – ø-ƿ (U+00F8-U+01BF – C0 controls, Latin extended A & B) \199\132-\201\143 – DŽ-ɏ (U+01C4-U+024F – Latin extended B) ]] local function is_good_vanc_name (last, first, suffix, position) if not suffix then if first:find ('[,%s]') then -- when there is a space or comma, might be first name/initials + generational suffix first = first:match ('(.-)[,%s]+'); -- get name/initials suffix = first:match ('[,%s]+(.+)$'); -- get generational suffix end end if utilities.is_set (suffix) then if not is_suffix (suffix) then add_vanc_error (cfg.err_msg_supl.suffix, position); return false; -- not a name with an appropriate suffix end end if nil == mw.ustring.find (last, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143%-%s%']*$") or nil == mw.ustring.find (first, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143%-%s%'%.]*$") then add_vanc_error (cfg.err_msg_supl['non-Latin char'], position); return false; -- not a string of Latin characters; Vancouver requires Romanization end; return true; end --[[--------------------------< R E D U C E _ T O _ I N I T I A L S >------------------------------------------ Attempts to convert names to initials in support of |name-list-style=vanc. Names in |firstn= may be separated by spaces or hyphens, or for initials, a period. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35062/. Vancouver style requires family rank designations (Jr, II, III, etc.) to be rendered as Jr, 2nd, 3rd, etc. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35085/. This code only accepts and understands generational suffix in the Vancouver format because Roman numerals look like, and can be mistaken for, initials. This function uses ustring functions because firstname initials may be any of the Unicode Latin characters accepted by is_good_vanc_name (). ]] local function reduce_to_initials(first, position) local name, suffix = mw.ustring.match(first, "^(%u+) ([%dJS][%drndth]+)$"); if not name then -- if not initials and a suffix name = mw.ustring.match(first, "^(%u+)$"); -- is it just initials? end if name then -- if first is initials with or without suffix if 3 > mw.ustring.len (name) then -- if one or two initials if suffix then -- if there is a suffix if is_suffix (suffix) then -- is it legitimate? return first; -- one or two initials and a valid suffix so nothing to do else add_vanc_error (cfg.err_msg_supl.suffix, position); -- one or two initials with invalid suffix so error message return first; -- and return first unmolested end else return first; -- one or two initials without suffix; nothing to do end end end -- if here then name has 3 or more uppercase letters so treat them as a word local initials, names = {}, {}; -- tables to hold name parts and initials local i = 1; -- counter for number of initials names = mw.text.split (first, '[%s,]+'); -- split into a table of names and possible suffix while names[i] do -- loop through the table if 1 < i and names[i]:match ('[%dJS][%drndth]+%.?$') then -- if not the first name, and looks like a suffix (may have trailing dot) names[i] = names[i]:gsub ('%.', ''); -- remove terminal dot if present if is_suffix (names[i]) then -- if a legitimate suffix table.insert (initials, ' ' .. names[i]); -- add a separator space, insert at end of initials table break; -- and done because suffix must fall at the end of a name end -- no error message if not a suffix; possibly because of Romanization end if 3 > i then table.insert (initials, mw.ustring.sub(names[i], 1, 1)); -- insert the initial at end of initials table end i = i + 1; -- bump the counter end return table.concat(initials) -- Vancouver format does not include spaces. end --[[--------------------------< I N T E R W I K I _ P R E F I X E N _ G E T >---------------------------------- extract interwiki prefixen from <value>. Returns two one or two values: false – no prefixen nil – prefix exists but not recognized project prefix, language prefix – when value has either of: :<project>:<language>:<article> :<language>:<project>:<article> project prefix, nil – when <value> has only a known single-letter prefix nil, language prefix – when <value> has only a known language prefix accepts single-letter project prefixen: 'd' (wikidata), 's' (wikisource), and 'w' (wikipedia) prefixes; at this writing, the other single-letter prefixen (b (wikibook), c (commons), m (meta), n (wikinews), q (wikiquote), and v (wikiversity)) are not supported. ]] local function interwiki_prefixen_get (value, is_link) if not value:find (':%l+:') then -- if no prefix return false; -- abandon; boolean here to distinguish from nil fail returns later end local prefix_patterns_linked_t = { -- sequence of valid interwiki and inter project prefixen '^%[%[:([dsw]):(%l%l+):', -- wikilinked; project and language prefixes '^%[%[:(%l%l+):([dsw]):', -- wikilinked; language and project prefixes '^%[%[:([dsw]):', -- wikilinked; project prefix '^%[%[:(%l%l+):', -- wikilinked; language prefix } local prefix_patterns_unlinked_t = { -- sequence of valid interwiki and inter project prefixen '^:([dsw]):(%l%l+):', -- project and language prefixes '^:(%l%l+):([dsw]):', -- language and project prefixes '^:([dsw]):', -- project prefix '^:(%l%l+):', -- language prefix } local cap1, cap2; for _, pattern in ipairs ((is_link and prefix_patterns_linked_t) or prefix_patterns_unlinked_t) do cap1, cap2 = value:match (pattern); if cap1 then break; -- found a match so stop looking end end if cap1 and cap2 then -- when both then :project:language: or :language:project: (both forms allowed) if 1 == #cap1 then -- length == 1 then :project:language: if cfg.inter_wiki_map[cap2] then -- is language prefix in the interwiki map? return cap1, cap2; -- return interwiki project and interwiki language end else -- here when :language:project: if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map? return cap2, cap1; -- return interwiki project and interwiki language end end return nil; -- unknown interwiki language elseif not (cap1 or cap2) then -- both are nil? return nil; -- we got something that looks like a project prefix but isn't; return fail elseif 1 == #cap1 then -- here when one capture return cap1, nil; -- length is 1 so return project, nil language else -- here when one capture and its length it more than 1 if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map? return nil, cap1; -- return nil project, language end end end --[[--------------------------< L I S T _ P E O P L E >-------------------------- Formats a list of people (authors, contributors, editors, interviewers, translators) names in the list will be linked when |<name>-link= has a value |<name>-mask- does NOT have a value; masked names are presumed to have been rendered previously so should have been linked there when |<name>-mask=0, the associated name is not rendered ]] local function list_people (control, people, etal) local sep; local namesep; local format = control.format; local maximum = control.maximum; local name_list = {}; if 'vanc' == format then -- Vancouver-like name styling? sep = cfg.presentation['sep_nl_vanc']; -- name-list separator between names is a comma namesep = cfg.presentation['sep_name_vanc']; -- last/first separator is a space else sep = cfg.presentation['sep_nl']; -- name-list separator between names is a semicolon namesep = cfg.presentation['sep_name']; -- last/first separator is <comma><space> end if sep:sub (-1, -1) ~= " " then sep = sep .. " " end if utilities.is_set (maximum) and maximum < 1 then return "", 0; end -- returned 0 is for EditorCount; not used for other names for i, person in ipairs (people) do if utilities.is_set (person.last) then local mask = person.mask; local one; local sep_one = sep; if utilities.is_set (maximum) and i > maximum then etal = true; break; end if mask then local n = tonumber (mask); -- convert to a number if it can be converted; nil else if n then one = 0 ~= n and string.rep("&mdash;", n) or nil; -- make a string of (n > 0) mdashes, nil else, to replace name person.link = nil; -- don't create link to name if name is replaces with mdash string or has been set nil else one = mask; -- replace name with mask text (must include name-list separator) sep_one = " "; -- modify name-list separator end else one = person.last; -- get surname local first = person.first -- get given name if utilities.is_set (first) then if ("vanc" == format) then -- if Vancouver format one = one:gsub ('%.', ''); -- remove periods from surnames (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/) if not person.corporate and is_good_vanc_name (one, first, nil, i) then -- and name is all Latin characters; corporate authors not tested first = reduce_to_initials (first, i); -- attempt to convert first name(s) to initials end end one = one .. namesep .. first; end end if utilities.is_set (person.link) then one = utilities.make_wikilink (person.link, one); -- link author/editor end if one then -- if <one> has a value (name, mdash replacement, or mask text replacement) local proj, tag = interwiki_prefixen_get (one, true); -- get the interwiki prefixen if present if 'w' == proj and ('Wikipedia' == mw.site.namespaces.Project['name']) then proj = nil; -- for stuff like :w:de:<article>, :w is unnecessary TODO: maint cat? end if proj then proj = ({['d'] = 'Wikidata', ['s'] = 'Wikisource', ['w'] = 'Wikipedia'})[proj]; -- :w (wikipedia) for linking from a non-wikipedia project if proj then one = one .. utilities.wrap_style ('interproj', proj); -- add resized leading space, brackets, static text, language name tag = nil; -- unset; don't do both project and language end end if tag == cfg.this_wiki_code then tag = nil; -- stuff like :en:<article> at en.wiki is pointless TODO: maint cat? end if tag then local lang = cfg.lang_tag_remap[tag] or cfg.mw_languages_by_tag_t[tag]; if lang then -- error messaging done in extract_names() where we know parameter names one = one .. utilities.wrap_style ('interwiki', lang); -- add resized leading space, brackets, static text, language name end end table.insert (name_list, one); -- add it to the list of names table.insert (name_list, sep_one); -- add the proper name-list separator end end end local count = #name_list / 2; -- (number of names + number of separators) divided by 2 if 0 < count then if 1 < count and not etal then if 'amp' == format then name_list[#name_list-2] = " & "; -- replace last separator with ampersand text elseif 'and' == format then if 2 == count then name_list[#name_list-2] = cfg.presentation.sep_nl_and; -- replace last separator with 'and' text else name_list[#name_list-2] = cfg.presentation.sep_nl_end; -- replace last separator with '(sep) and' text end end end name_list[#name_list] = nil; -- erase the last separator end local result = table.concat (name_list); -- construct list if etal and utilities.is_set (result) then -- etal may be set by |display-authors=etal but we might not have a last-first list result = result .. sep .. cfg.messages['et al']; -- we've got a last-first list and etal so add et al. end return result, count; -- return name-list string and count of number of names (count used for editor names only) end --[[--------------------< M A K E _ C I T E R E F _ I D >----------------------- Generates a CITEREF anchor ID if we have at least one name or a date. Otherwise returns an empty string. namelist is one of the contributor-, author-, or editor-name lists chosen in that order. year is Year or anchor_year. ]] local function make_citeref_id (namelist, year) local names={}; -- a table for the one to four names and year for i,v in ipairs (namelist) do -- loop through the list and take up to the first four last names names[i] = v.last if i == 4 then break end -- if four then done end table.insert (names, year); -- add the year at the end local id = table.concat(names); -- concatenate names and year for CITEREF id if utilities.is_set (id) then -- if concatenation is not an empty string return "CITEREF" .. id; -- add the CITEREF portion else return ''; -- return an empty string; no reason to include CITEREF id in this citation end end --[[--------------------------< C I T E _ C L A S S _A T T R I B U T E _M A K E >------------------------------ construct <cite> tag class attribute for this citation. <cite_class> – config.CitationClass from calling template <mode> – value from |mode= parameter ]] local function cite_class_attribute_make (cite_class, mode) local class_t = {}; table.insert (class_t, 'citation'); -- required for blue highlight if 'citation' ~= cite_class then table.insert (class_t, cite_class); -- identify this template for user css table.insert (class_t, utilities.is_set (mode) and mode or 'cs1'); -- identify the citation style for user css or javascript else table.insert (class_t, utilities.is_set (mode) and mode or 'cs2'); -- identify the citation style for user css or javascript end for _, prop_key in ipairs (z.prop_keys_t) do table.insert (class_t, prop_key); -- identify various properties for user css or javascript end return table.concat (class_t, ' '); -- make a big string and done end --[[---------------------< N A M E _ H A S _ E T A L >-------------------------- Evaluates the content of name parameters (author, editor, etc.) for variations on the theme of et al. If found, the et al. is removed, a flag is set to true and the function returns the modified name and the flag. This function never sets the flag to false but returns its previous state because it may have been set by previous passes through this function or by the associated |display-<names>=etal parameter ]] local function name_has_etal (name, etal, nocat, param) if utilities.is_set (name) then -- name can be nil in which case just return local patterns = cfg.et_al_patterns; -- get patterns from configuration for _, pattern in ipairs (patterns) do -- loop through all of the patterns if name:match (pattern) then -- if this 'et al' pattern is found in name name = name:gsub (pattern, ''); -- remove the offending text etal = true; -- set flag (may have been set previously here or by |display-<names>=etal) if not nocat then -- no categorization for |vauthors= utilities.set_message ('err_etal', {param}); -- and set an error if not added end end end end return name, etal; end --[[---------------------< N A M E _ I S _ N U M E R I C >---------------------- Add maint cat when name parameter value does not contain letters. Does not catch mixed alphanumeric names so |last=A. Green (1922-1987) does not get caught in the current version of this test but |first=(1888) is caught. returns nothing ]] local function name_is_numeric (name, list_name) if utilities.is_set (name) then if mw.ustring.match (name, '^[%A]+$') then -- when name does not contain any letters utilities.set_message ('maint_numeric_names', cfg.special_case_translation [list_name]); -- add a maint cat for this template end end end --[[-----------------< N A M E _ H A S _ M U L T _ N A M E S >------------------ Evaluates the content of last/surname (authors etc.) parameters for multiple names. Multiple names are indicated if there is more than one comma or any "unescaped" semicolons. Escaped semicolons are ones used as part of selected HTML entities. If the condition is met, the function adds the multiple name maintenance category. Same test for first except that commas should not appear in given names (MOS:JR says that the generational suffix does not take a separator character). Titles, degrees, postnominals, affiliations, all normally comma separated don't belong in a citation. <name> – name parameter value <list_name> – AuthorList, EditorList, etc <limit> – number of allowed commas; 1 (default) for surnames; 0 for given names returns nothing ]] local function name_has_mult_names (name, list_name, limit) local _, commas, semicolons, nbsps; limit = limit and limit or 1; if utilities.is_set (name) then _, commas = name:gsub (',', ''); -- count the number of commas _, semicolons = name:gsub (';', ''); -- count the number of semicolons -- nbsps probably should be its own separate count rather than merged in -- some way with semicolons because Lua patterns do not support the -- grouping operator that regex does, which means there is no way to add -- more entities to escape except by adding more counts with the new -- entities _, nbsps = name:gsub ('&nbsp;',''); -- count nbsps -- There is exactly 1 semicolon per &nbsp; entity, so subtract nbsps -- from semicolons to 'escape' them. If additional entities are added, -- they also can be subtracted. if limit < commas or 0 < (semicolons - nbsps) then utilities.set_message ('maint_mult_names', cfg.special_case_translation [list_name]); -- add a maint message end end end --[=[-------------------------< I S _ G E N E R I C >---------------------------------------------------------- Compares values assigned to various parameters according to the string provided as <item> in the function call. <item> can have on of two values: 'generic_names' – for name-holding parameters: |last=, |first=, |editor-last=, etc 'generic_titles' – for |title= There are two types of generic tests. The 'accept' tests look for a pattern that should not be rejected by the 'reject' test. For example, |author=[[John Smith (author)|Smith, John]] would be rejected by the 'author' reject test. But piped wikilinks with 'author' disambiguation should not be rejected so the 'accept' test prevents that from happening. Accept tests are always performed before reject tests. Each of the 'accept' and 'reject' sequence tables hold tables for en.wiki (['en']) and local.wiki (['local']) that each can hold a test sequence table The sequence table holds, at index [1], a test pattern, and, at index [2], a boolean control value. The control value tells string.find() or mw.ustring.find() to do plain-text search (true) or a pattern search (false). The intent of all this complexity is to make these searches as fast as possible so that we don't run out of processing time on very large articles. Returns true when a reject test finds the pattern or string false when an accept test finds the pattern or string nil else ]=] local function is_generic (item, value, wiki) local test_val; local str_lower = { -- use string.lower() for en.wiki (['en']) and use mw.ustring.lower() or local.wiki (['local']) ['en'] = string.lower, ['local'] = mw.ustring.lower, } local str_find = { -- use string.find() for en.wiki (['en']) and use mw.ustring.find() or local.wiki (['local']) ['en'] = string.find, ['local'] = mw.ustring.find, } local function test (val, test_t, wiki) -- local function to do the testing; <wiki> selects lower() and find() functions val = test_t[2] and str_lower[wiki](value) or val; -- when <test_t[2]> set to 'true', plaintext search using lowercase value return str_find[wiki] (val, test_t[1], 1, test_t[2]); -- return nil when not found or matched end local test_types_t = {'accept', 'reject'}; -- test accept patterns first, then reject patterns local wikis_t = {'en', 'local'}; -- do tests for each of these keys; en.wiki first, local.wiki second for _, test_type in ipairs (test_types_t) do -- for each test type for _, generic_value in pairs (cfg.special_case_translation[item][test_type]) do -- spin through the list of generic value fragments to accept or reject for _, wiki in ipairs (wikis_t) do if generic_value[wiki] then if test (value, generic_value[wiki], wiki) then -- go do the test return ('reject' == test_type); -- param value rejected, return true; false else end end end end end end --[[--------------------------< N A M E _ I S _ G E N E R I C >------------------------------------------------ calls is_generic() to determine if <name> is a 'generic name' listed in cfg.generic_names; <name_alias> is the parameter name used in error messaging ]] local function name_is_generic (name, name_alias) if not added_generic_name_errs and is_generic ('generic_names', name) then utilities.set_message ('err_generic_name', name_alias); -- set an error message added_generic_name_errs = true; end end --[[--------------------------< N A M E _ C H E C K S >-------------------------------------------------------- This function calls various name checking functions used to validate the content of the various name-holding parameters. ]] local function name_checks (last, first, list_name, last_alias, first_alias) local accept_name; if utilities.is_set (last) then last, accept_name = utilities.has_accept_as_written (last); -- remove accept-this-as-written markup when it wraps all of <last> if not accept_name then -- <last> not wrapped in accept-as-written markup name_has_mult_names (last, list_name); -- check for multiple names in the parameter name_is_numeric (last, list_name); -- check for names that are composed of digits and punctuation name_is_generic (last, last_alias); -- check for names found in the generic names list end end if utilities.is_set (first) then first, accept_name = utilities.has_accept_as_written (first); -- remove accept-this-as-written markup when it wraps all of <first> if not accept_name then -- <first> not wrapped in accept-as-written markup name_has_mult_names (first, list_name, 0); -- check for multiple names in the parameter; 0 is number of allowed commas in a given name name_is_numeric (first, list_name); -- check for names that are composed of digits and punctuation name_is_generic (first, first_alias); -- check for names found in the generic names list end local wl_type, D = utilities.is_wikilink (first); if 0 ~= wl_type then first = D; utilities.set_message ('err_bad_paramlink', first_alias); end end return last, first; -- done end --[[----------------------< E X T R A C T _ N A M E S >------------------------- Gets name list from the input arguments Searches through args in sequential order to find |lastn= and |firstn= parameters (or their aliases), and their matching link and mask parameters. Stops searching when both |lastn= and |firstn= are not found in args after two sequential attempts: found |last1=, |last2=, and |last3= but doesn't find |last4= and |last5= then the search is done. This function emits an error message when there is a |firstn= without a matching |lastn=. When there are 'holes' in the list of last names, |last1= and |last3= are present but |last2= is missing, an error message is emitted. |lastn= is not required to have a matching |firstn=. When an author or editor parameter contains some form of 'et al.', the 'et al.' is stripped from the parameter and a flag (etal) returned that will cause list_people() to add the static 'et al.' text from Module:Citation/CS1/Configuration. This keeps 'et al.' out of the template's metadata. When this occurs, an error is emitted. ]] local function extract_names(args, list_name) local names = {}; -- table of names local last; -- individual name components local first; local link; local mask; local i = 1; -- loop counter/indexer local n = 1; -- output table indexer local count = 0; -- used to count the number of times we haven't found a |last= (or alias for authors, |editor-last or alias for editors) local etal = false; -- return value set to true when we find some form of et al. in an author parameter local last_alias, first_alias, link_alias; -- selected parameter aliases used in error messaging while true do last, last_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'err_redundant_parameters', i ); -- search through args for name components beginning at 1 first, first_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'err_redundant_parameters', i ); link, link_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ); mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i ); if last then -- error check |lastn= alias for unknown interwiki link prefix; done here because this is where we have the parameter name local project, language = interwiki_prefixen_get (last, true); -- true because we expect interwiki links in |lastn= to be wikilinked if nil == project and nil == language then -- when both are nil utilities.set_message ('err_bad_paramlink', last_alias); -- not known, emit an error message -- TODO: err_bad_interwiki? last = utilities.remove_wiki_link (last); -- remove wikilink markup; show display value only end end if link then -- error check |linkn= alias for unknown interwiki link prefix local project, language = interwiki_prefixen_get (link, false); -- false because wiki links in |author-linkn= is an error if nil == project and nil == language then -- when both are nil utilities.set_message ('err_bad_paramlink', link_alias); -- not known, emit an error message -- TODO: err_bad_interwiki? link = nil; -- unset so we don't link link_alias = nil; end end last, etal = name_has_etal (last, etal, false, last_alias); -- find and remove variations on et al. first, etal = name_has_etal (first, etal, false, first_alias); -- find and remove variations on et al. last, first = name_checks (last, first, list_name, last_alias, first_alias); -- multiple names, extraneous annotation, etc. checks if first and not last then -- if there is a firstn without a matching lastn local alias = first_alias:find ('given', 1, true) and 'given' or 'first'; -- get first or given form of the alias utilities.set_message ('err_first_missing_last', { first_alias, -- param name of alias missing its mate first_alias:gsub (alias, {['first'] = 'last', ['given'] = 'surname'}), -- make param name appropriate to the alias form }); -- add this error message elseif not first and not last then -- if both firstn and lastn aren't found, are we done? count = count + 1; -- number of times we haven't found last and first if 2 <= count then -- two missing names and we give up break; -- normal exit or there is a two-name hole in the list; can't tell which end else -- we have last with or without a first local result; link = link_title_ok (link, link_alias, last, last_alias); -- check for improper wiki-markup if first then link = link_title_ok (link, link_alias, first, first_alias); -- check for improper wiki-markup end names[n] = {last = last, first = first, link = link, mask = mask, corporate = false}; -- add this name to our names list (corporate for |vauthors= only) n = n + 1; -- point to next location in the names table if 1 == count then -- if the previous name was missing utilities.set_message ('err_missing_name', {list_name:match ("(%w+)List"):lower(), i - 1}); -- add this error message end count = 0; -- reset the counter, we're looking for two consecutive missing names end i = i + 1; -- point to next args location end return names, etal; -- all done, return our list of names and the etal flag end --[[--------------------------< N A M E _ T A G _ G E T >------------------------------------------------------ attempt to decode |language=<lang_param> and return language name and matching tag; nil else. This function looks for: <lang_param> as a tag in cfg.lang_tag_remap{} <lang_param> as a name in cfg.lang_name_remap{} <lang_param> as a name in cfg.mw_languages_by_name_t <lang_param> as a tag in cfg.mw_languages_by_tag_t when those fail, presume that <lang_param> is an IETF-like tag that MediaWiki does not recognize. Strip all script, region, variant, whatever subtags from <lang_param> to leave just a two or three character language tag and look for the new <lang_param> in cfg.mw_languages_by_tag_t{} on success, returns name (in properly capitalized form) and matching tag (in lowercase); on failure returns nil ]] local function name_tag_get (lang_param) local lang_param_lc = mw.ustring.lower (lang_param); -- use lowercase as an index into the various tables local name; local tag; name = cfg.lang_tag_remap[lang_param_lc]; -- assume <lang_param_lc> is a tag; attempt to get remapped language name if name then -- when <name>, <lang_param> is a tag for a remapped language name return name, lang_param_lc; -- so return <name> from remap and <lang_param_lc> end tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- still assuming that <lang_param_lc> is a tag; strip script, region, variant subtags name = cfg.lang_tag_remap[tag]; -- attempt to get remapped language name with language subtag only if name then -- when <name>, <tag> is a tag for a remapped language name return name, tag; -- so return <name> from remap and <tag> end if cfg.lang_name_remap[lang_param_lc] then -- not a tag, assume <lang_param_lc> is a name; attempt to get remapped language tag return cfg.lang_name_remap[lang_param_lc][1], cfg.lang_name_remap[lang_param_lc][2]; -- for this <lang_param_lc>, return a (possibly) new name and appropriate tag end tag = cfg.mw_languages_by_name_t[lang_param_lc]; -- assume that <lang_param_lc> is a language name; attempt to get its matching tag if tag then return cfg.mw_languages_by_tag_t[tag], tag; -- <lang_param_lc> is a name so return the name from the table and <tag> end name = cfg.mw_languages_by_tag_t[lang_param_lc]; -- assume that <lang_param_lc> is a tag; attempt to get its matching language name if name then return name, lang_param_lc; -- <lang_param_lc> is a tag so return it and <name> end tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- is <lang_param_lc> an IETF-like tag that MediaWiki doesn't recognize? <tag> gets the language subtag; nil else if tag then name = cfg.mw_languages_by_tag_t[tag]; -- attempt to get a language name using the shortened <tag> if name then return name, tag; -- <lang_param_lc> is an unrecognized IETF-like tag so return <name> and language subtag end end end --[[-------------------< L A N G U A G E _ P A R A M E T E R >------------------ Gets language name from a provided two- or three-character ISO 639 code. If a code is recognized by MediaWiki, use the returned name; if not, then use the value that was provided with the language parameter. When |language= contains a recognized language (either code or name), the page is assigned to the category for that code: Category:Norwegian-language sources (no). For valid three-character code languages, the page is assigned to the single category for '639-2' codes: Category:CS1 ISO 639-2 language sources. Languages that are the same as the local wiki are not categorized. MediaWiki does not recognize three-character equivalents of two-character codes: code 'ar' is recognized but code 'ara' is not. This function supports multiple languages in the form |language=nb, French, th where the language names or codes are separated from each other by commas with optional space characters. ]] local function language_parameter (lang) local tag; -- some form of IETF-like language tag; language subtag with optional region, sript, vatiant, etc subtags local lang_subtag; -- ve populates |language= with mostly unecessary region subtags the MediaWiki does not recognize; this is the base language subtag local name; -- the language name local language_list = {}; -- table of language names to be rendered local names_t = {}; -- table made from the value assigned to |language= local this_wiki_name = mw.language.fetchLanguageName (cfg.this_wiki_code, cfg.this_wiki_code); -- get this wiki's language name names_t = mw.text.split (lang, '%s*,%s*'); -- names should be a comma separated list for _, lang in ipairs (names_t) do -- reuse lang here because we don't yet know if lang is a language name or a language tag name, tag = name_tag_get (lang); -- attempt to get name/tag pair for <lang>; <name> has proper capitalization; <tag> is lowercase if utilities.is_set (tag) then lang_subtag = tag:gsub ('^(%a%a%a?)%-.*', '%1'); -- for categorization, strip any IETF-like tags from language tag if cfg.this_wiki_code ~= lang_subtag then -- when the language is not the same as this wiki's language if 2 == lang_subtag:len() then -- and is a two-character tag utilities.add_prop_cat ('foreign-lang-source', {name, tag}, lang_subtag); -- categorize it; tag appended to allow for multiple language categorization else -- or is a recognized language (but has a three-character tag) utilities.add_prop_cat ('foreign-lang-source-2', {lang_subtag}, lang_subtag); -- categorize it differently TODO: support multiple three-character tag categories per cs1|2 template? end elseif cfg.local_lang_cat_enable then -- when the language and this wiki's language are the same and categorization is enabled utilities.add_prop_cat ('local-lang-source', {name, lang_subtag}); -- categorize it end else name = lang; -- return whatever <lang> has so that we show something utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added end table.insert (language_list, name); name = ''; -- so we can reuse it end name = utilities.make_sep_list (#language_list, language_list); if (1 == #language_list) and (lang_subtag == cfg.this_wiki_code) then -- when only one language, find lang name in this wiki lang name; for |language=en-us, 'English' in 'American English' return ''; -- if one language and that language is this wiki's return an empty string (no annotation) end return (" " .. wrap_msg ('language', name)); -- otherwise wrap with '(in ...)' --[[ TODO: should only return blank or name rather than full list so we can clean up the bunched parenthetical elements Language, Type, Format ]] end --[[-----------------------< S E T _ C S _ S T Y L E >-------------------------- Gets the default CS style configuration for the given mode. Returns default separator and either postscript as passed in or the default. In CS1, the default postscript and separator are '.'. In CS2, the default postscript is the empty string and the default separator is ','. ]] local function set_cs_style (postscript, mode) if utilities.is_set(postscript) then -- emit a maintenance message if user postscript is the default cs1 postscript -- we catch the opposite case for cs2 in set_style if mode == 'cs1' and postscript == cfg.presentation['ps_' .. mode] then utilities.set_message ('maint_postscript'); end else postscript = cfg.presentation['ps_' .. mode]; end return cfg.presentation['sep_' .. mode], postscript; end --[[--------------------------< S E T _ S T Y L E >----------------------------- Sets the separator and postscript styles. Checks the |mode= first and the #invoke CitationClass second. Removes the postscript if postscript == none. ]] local function set_style (mode, postscript, cite_class) local sep; if 'cs2' == mode then sep, postscript = set_cs_style (postscript, 'cs2'); elseif 'cs1' == mode then sep, postscript = set_cs_style (postscript, 'cs1'); elseif 'citation' == cite_class then sep, postscript = set_cs_style (postscript, 'cs2'); else sep, postscript = set_cs_style (postscript, 'cs1'); end if cfg.keywords_xlate[postscript:lower()] == 'none' then -- emit a maintenance message if user postscript is the default cs2 postscript -- we catch the opposite case for cs1 in set_cs_style if 'cs2' == mode or 'citation' == cite_class then utilities.set_message ('maint_postscript'); end postscript = ''; end return sep, postscript end --[=[-------------------------< I S _ P D F >----------------------------------- Determines if a URL has the file extension that is one of the PDF file extensions used by [[MediaWiki:Common.css]] when applying the PDF icon to external links. returns true if file extension is one of the recognized extensions, else false ]=] local function is_pdf (url) return url:match ('%.pdf$') or url:match ('%.PDF$') or url:match ('%.pdf[%?#]') or url:match ('%.PDF[%?#]') or url:match ('%.PDF&#035') or url:match ('%.pdf&#035'); end --[[--------------------------< S T Y L E _ F O R M A T >----------------------- Applies CSS style to |format=, |chapter-format=, etc. Also emits an error message if the format parameter does not have a matching URL parameter. If the format parameter is not set and the URL contains a file extension that is recognized as a PDF document by MediaWiki's commons.css, this code will set the format parameter to (PDF) with the appropriate styling. ]] local function style_format (format, url, fmt_param, url_param) if utilities.is_set (format) then format = utilities.wrap_style ('format', format); -- add leading space, parentheses, resize if not utilities.is_set (url) then utilities.set_message ('err_format_missing_url', {fmt_param, url_param}); -- add an error message end elseif is_pdf (url) then -- format is not set so if URL is a PDF file then format = utilities.wrap_style ('format', 'PDF'); -- set format to PDF else format = ''; -- empty string for concatenation end return format; end --[[---------------------< G E T _ D I S P L A Y _ N A M E S >------------------ Returns a number that defines the number of names displayed for author and editor name lists and a Boolean flag to indicate when et al. should be appended to the name list. When the value assigned to |display-xxxxors= is a number greater than or equal to zero, return the number and the previous state of the 'etal' flag (false by default but may have been set to true if the name list contains some variant of the text 'et al.'). When the value assigned to |display-xxxxors= is the keyword 'etal', return a number that is one greater than the number of authors in the list and set the 'etal' flag true. This will cause the list_people() to display all of the names in the name list followed by 'et al.' In all other cases, returns nil and the previous state of the 'etal' flag. inputs: max: A['DisplayAuthors'] or A['DisplayEditors'], etc; a number or some flavor of etal count: #a or #e list_name: 'authors' or 'editors' etal: author_etal or editor_etal This function sets an error message when |display-xxxxors= value greater than or equal to number of names but not when <max> comes from {{cs1 config}} global settings. When using global settings, <param> is set to the keyword 'cs1 config' which is used to supress the normal error. Error is suppressed because it is to be expected that some citations in an article will have the same or fewer names that the limit specified in {{cs1 config}}. ]] local function get_display_names (max, count, list_name, etal, param) if utilities.is_set (max) then if 'etal' == max:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings max = count + 1; -- number of authors + 1 so display all author name plus et al. etal = true; -- overrides value set by extract_names() elseif max:match ('^%d+$') then -- if is a string of numbers max = tonumber (max); -- make it a number if (max >= count) and ('cs1 config' ~= param) then -- error when local |display-xxxxors= value greater than or equal to number of names; not an error when using global setting utilities.set_message ('err_disp_name', {param, max}); -- add error message max = nil; end else -- not a valid keyword or number utilities.set_message ('err_disp_name', {param, max}); -- add error message max = nil; -- unset; as if |display-xxxxors= had not been set end end return max, etal; end --[[----------< E X T R A _ T E X T _ I N _ P A G E _ C H E C K >--------------- Adds error if |page=, |pages=, |quote-page=, |quote-pages= has what appears to be some form of p. or pp. abbreviation in the first characters of the parameter content. check page for extraneous p, p., pp, pp., pg, pg. at start of parameter value: good pattern: '^P[^%.P%l]' matches when page begins PX or P# but not Px where x and X are letters and # is a digit bad pattern: '^[Pp][PpGg]' matches when page begins pp, pP, Pp, PP, pg, pG, Pg, PG ]] local function extra_text_in_page_check (val, name) if not val:match (cfg.vol_iss_pg_patterns.good_ppattern) then for _, pattern in ipairs (cfg.vol_iss_pg_patterns.bad_ppatterns) do -- spin through the selected sequence table of patterns if val:match (pattern) then -- when a match, error so utilities.set_message ('err_extra_text_pages', name); -- add error message return; -- and done end end end end --[[--------------------------< E X T R A _ T E X T _ I N _ V O L _ I S S _ C H E C K >------------------------ Adds error if |volume= or |issue= has what appears to be some form of redundant 'type' indicator. For |volume=: 'V.', or 'Vol.' (with or without the dot) abbreviations or 'Volume' in the first characters of the parameter content (all case insensitive). 'V' and 'v' (without the dot) are presumed to be roman numerals so are allowed. For |issue=: 'No.', 'I.', 'Iss.' (with or without the dot) abbreviations, or 'Issue' in the first characters of the parameter content (all case insensitive). Single character values ('v', 'i', 'n') allowed when not followed by separator character ('.', ':', '=', or whitespace character) – param values are trimmed of whitespace by MediaWiki before delivered to the module. <val> is |volume= or |issue= parameter value <name> is |volume= or |issue= parameter name for error message <selector> is 'v' for |volume=, 'i' for |issue= sets error message on failure; returns nothing ]] local function extra_text_in_vol_iss_check (val, name, selector) if not utilities.is_set (val) then return; end local patterns = 'v' == selector and cfg.vol_iss_pg_patterns.vpatterns or cfg.vol_iss_pg_patterns.ipatterns; local handler = 'v' == selector and 'err_extra_text_volume' or 'err_extra_text_issue'; val = val:lower(); -- force parameter value to lower case for _, pattern in ipairs (patterns) do -- spin through the selected sequence table of patterns if val:match (pattern) then -- when a match, error so utilities.set_message (handler, name); -- add error message return; -- and done end end end --[=[-------------------------< G E T _ V _ N A M E _ T A B L E >---------------------------------------------- split apart a |vauthors= or |veditors= parameter. This function allows for corporate names, wrapped in doubled parentheses to also have commas; in the old version of the code, the doubled parentheses were included in the rendered citation and in the metadata. Individual author names may be wikilinked |vauthors=Jones AB, [[E. B. White|White EB]], ((Black, Brown, and Co.)) ]=] local function get_v_name_table (vparam, output_table, output_link_table) local name_table = mw.text.split(vparam, "%s*,%s*"); -- names are separated by commas local wl_type, label, link; -- wl_type not used here; just a placeholder local i = 1; while name_table[i] do if name_table[i]:match ('^%(%(.*[^%)][^%)]$') then -- first segment of corporate with one or more commas; this segment has the opening doubled parentheses local name = name_table[i]; i = i + 1; -- bump indexer to next segment while name_table[i] do name = name .. ', ' .. name_table[i]; -- concatenate with previous segments if name_table[i]:match ('^.*%)%)$') then -- if this table member has the closing doubled parentheses break; -- and done reassembling so end i = i + 1; -- bump indexer end table.insert (output_table, name); -- and add corporate name to the output table table.insert (output_link_table, ''); -- no wikilink else wl_type, label, link = utilities.is_wikilink (name_table[i]); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]] table.insert (output_table, label); -- add this name if 1 == wl_type then table.insert (output_link_table, label); -- simple wikilink [[D]] else table.insert (output_link_table, link); -- no wikilink or [[L|D]]; add this link if there is one, else empty string end end i = i + 1; end return output_table; end --[[--------------------------< P A R S E _ V A U T H O R S _ V E D I T O R S >-------------------------------- This function extracts author / editor names from |vauthors= or |veditors= and finds matching |xxxxor-maskn= and |xxxxor-linkn= in args. It then returns a table of assembled names just as extract_names() does. Author / editor names in |vauthors= or |veditors= must be in Vancouver system style. Corporate or institutional names may sometimes be required and because such names will often fail the is_good_vanc_name() and other format compliance tests, are wrapped in doubled parentheses ((corporate name)) to suppress the format tests. Supports generational suffixes Jr, 2nd, 3rd, 4th–6th. This function sets the Vancouver error when a required comma is missing and when there is a space between an author's initials. ]] local function parse_vauthors_veditors (args, vparam, list_name) local names = {}; -- table of names assembled from |vauthors=, |author-maskn=, |author-linkn= local v_name_table = {}; local v_link_table = {}; -- when name is wikilinked, targets go in this table local etal = false; -- return value set to true when we find some form of et al. vauthors parameter local last, first, link, mask, suffix; local corporate = false; vparam, etal = name_has_etal (vparam, etal, true); -- find and remove variations on et al. do not categorize (do it here because et al. might have a period) v_name_table = get_v_name_table (vparam, v_name_table, v_link_table); -- names are separated by commas for i, v_name in ipairs(v_name_table) do first = ''; -- set to empty string for concatenation and because it may have been set for previous author/editor local accept_name; v_name, accept_name = utilities.has_accept_as_written (v_name); -- remove accept-this-as-written markup when it wraps all of <v_name> if accept_name then last = v_name; corporate = true; -- flag used in list_people() elseif string.find(v_name, "%s") then if v_name:find('[;%.]') then -- look for commonly occurring punctuation characters; add_vanc_error (cfg.err_msg_supl.punctuation, i); end local lastfirstTable = {} lastfirstTable = mw.text.split(v_name, "%s+") first = table.remove(lastfirstTable); -- removes and returns value of last element in table which should be initials or generational suffix if not mw.ustring.match (first, '^%u+$') then -- mw.ustring here so that later we will catch non-Latin characters suffix = first; -- not initials so assume that whatever we got is a generational suffix first = table.remove(lastfirstTable); -- get what should be the initials from the table end last = table.concat(lastfirstTable, ' ') -- returns a string that is the concatenation of all other names that are not initials and generational suffix if not utilities.is_set (last) then first = ''; -- unset last = v_name; -- last empty because something wrong with first add_vanc_error (cfg.err_msg_supl.name, i); end if mw.ustring.match (last, '%a+%s+%u+%s+%a+') then add_vanc_error (cfg.err_msg_supl['missing comma'], i); -- matches last II last; the case when a comma is missing end if mw.ustring.match (v_name, ' %u %u$') then -- this test is in the wrong place TODO: move or replace with a more appropriate test add_vanc_error (cfg.err_msg_supl.initials, i); -- matches a space between two initials end else last = v_name; -- last name or single corporate name? Doesn't support multiword corporate names? do we need this? end if utilities.is_set (first) then if not mw.ustring.match (first, "^%u?%u$") then -- first shall contain one or two upper-case letters, nothing else add_vanc_error (cfg.err_msg_supl.initials, i); -- too many initials; mixed case initials (which may be ok Romanization); hyphenated initials end is_good_vanc_name (last, first, suffix, i); -- check first and last before restoring the suffix which may have a non-Latin digit if utilities.is_set (suffix) then first = first .. ' ' .. suffix; -- if there was a suffix concatenate with the initials suffix = ''; -- unset so we don't add this suffix to all subsequent names end else if not corporate then is_good_vanc_name (last, '', nil, i); end end link = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ) or v_link_table[i]; mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i ); names[i] = {last = last, first = first, link = link, mask = mask, corporate = corporate}; -- add this assembled name to our names list end return names, etal; -- all done, return our list of names end --[[--------------------------< S E L E C T _ A U T H O R _ E D I T O R _ S O U R C E >------------------------ Select one of |authors=, |authorn= / |lastn / firstn=, or |vauthors= as the source of the author name list or select one of |editorn= / editor-lastn= / |editor-firstn= or |veditors= as the source of the editor name list. Only one of these appropriate three will be used. The hierarchy is: |authorn= (and aliases) highest and |authors= lowest; |editorn= (and aliases) highest and |veditors= lowest (support for |editors= withdrawn) When looking for |authorn= / |editorn= parameters, test |xxxxor1= and |xxxxor2= (and all of their aliases); stops after the second test which mimicks the test used in extract_names() when looking for a hole in the author name list. There may be a better way to do this, I just haven't discovered what that way is. Emits an error message when more than one xxxxor name source is provided. In this function, vxxxxors = vauthors or veditors; xxxxors = authors as appropriate. ]] local function select_author_editor_source (vxxxxors, xxxxors, args, list_name) local lastfirst = false; if utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 1 ) or -- do this twice in case we have a |first1= without a |last1=; this ... utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 1 ) or -- ... also catches the case where |first= is used with |vauthors= utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 2 ) or utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 2 ) then lastfirst = true; end if (utilities.is_set (vxxxxors) and true == lastfirst) or -- these are the three error conditions (utilities.is_set (vxxxxors) and utilities.is_set (xxxxors)) or (true == lastfirst and utilities.is_set (xxxxors)) then local err_name; if 'AuthorList' == list_name then -- figure out which name should be used in error message err_name = 'author'; else err_name = 'editor'; end utilities.set_message ('err_redundant_parameters', err_name .. '-name-list parameters'); -- add error message end if true == lastfirst then return 1 end; -- return a number indicating which author name source to use if utilities.is_set (vxxxxors) then return 2 end; if utilities.is_set (xxxxors) then return 3 end; return 1; -- no authors so return 1; this allows missing author name test to run in case there is a first without last end --[[--------------------------< I S _ V A L I D _ P A R A M E T E R _ V A L U E >------------------------------ This function is used to validate a parameter's assigned value for those parameters that have only a limited number of allowable values (yes, y, true, live, dead, etc.). When the parameter value has not been assigned a value (missing or empty in the source template) the function returns the value specified by ret_val. If the parameter value is one of the list of allowed values returns the translated value; else, emits an error message and returns the value specified by ret_val. TODO: explain <invert> ]] local function is_valid_parameter_value (value, name, possible, ret_val, invert) if not utilities.is_set (value) then return ret_val; -- an empty parameter is ok end if (not invert and utilities.in_array (value, possible)) then -- normal; <value> is in <possible> table return cfg.keywords_xlate[value]; -- return translation of parameter keyword elseif invert and not utilities.in_array (value, possible) then -- invert; <value> is not in <possible> table return value; -- return <value> as it is else utilities.set_message ('err_invalid_param_val', {name, value}); -- not an allowed value so add error message return ret_val; end end --[[--------------------------< T E R M I N A T E _ N A M E _ L I S T >---------------------------------------- This function terminates a name list (author, contributor, editor) with a separator character (sepc) and a space when the last character is not a sepc character or when the last three characters are not sepc followed by two closing square brackets (close of a wikilink). When either of these is true, the name_list is terminated with a single space character. ]] local function terminate_name_list (name_list, sepc) if (string.sub (name_list, -3, -1) == sepc .. '. ') then -- if already properly terminated return name_list; -- just return the name list elseif (string.sub (name_list, -1, -1) == sepc) or (string.sub (name_list, -3, -1) == sepc .. ']]') then -- if last name in list ends with sepc char return name_list .. " "; -- don't add another else return name_list .. sepc .. ' '; -- otherwise terminate the name list end end --[[-------------------------< F O R M A T _ V O L U M E _ I S S U E >----------------------------------------- returns the concatenation of the formatted volume and issue (or journal article number) parameters as a single string; or formatted volume or formatted issue, or an empty string if neither are set. ]] local function format_volume_issue (volume, issue, article, cite_class, origin, sepc, lower) if not utilities.is_set (volume) and not utilities.is_set (issue) and not utilities.is_set (article) then return ''; end -- same condition as in format_pages_sheets() local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin); local is_numeric_vol = volume and (volume:match ('^[MDCLXVI]+$') or volume:match ('^%d+$')); -- is only uppercase roman numerals or only digits? local is_long_vol = volume and (4 < mw.ustring.len(volume)); -- is |volume= value longer than 4 characters? if volume and (not is_numeric_vol and is_long_vol) then -- when not all digits or Roman numerals, is |volume= longer than 4 characters? utilities.add_prop_cat ('long-vol'); -- yes, add properties cat end if is_journal then -- journal-style formatting local vol = ''; if utilities.is_set (volume) then if is_numeric_vol then -- |volume= value all digits or all uppercase Roman numerals? vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, volume}); -- render in bold face elseif is_long_vol then -- not all digits or Roman numerals; longer than 4 characters? vol = utilities.substitute (cfg.messages['j-vol'], {sepc, utilities.hyphen_to_dash (volume)}); -- not bold else -- four or fewer characters vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, utilities.hyphen_to_dash (volume)}); -- bold end end vol = vol .. (utilities.is_set (issue) and utilities.substitute (cfg.messages['j-issue'], issue) or '') vol = vol .. (utilities.is_set (article) and utilities.substitute (cfg.messages['j-article-num'], article) or '') return vol; end if 'podcast' == cite_class and utilities.is_set (issue) then return wrap_msg ('issue', {sepc, issue}, lower); end if 'conference' == cite_class and utilities.is_set (article) then -- |article-number= supported only in journal and conference cites if utilities.is_set (volume) and utilities.is_set (article) then -- both volume and article number return wrap_msg ('vol-art', {sepc, utilities.hyphen_to_dash (volume), article}, lower); elseif utilities.is_set (article) then -- article number alone; when volume alone, handled below return wrap_msg ('art', {sepc, article}, lower); end end -- all other types of citation if utilities.is_set (volume) and utilities.is_set (issue) then return wrap_msg ('vol-no', {sepc, utilities.hyphen_to_dash (volume), issue}, lower); elseif utilities.is_set (volume) then return wrap_msg ('vol', {sepc, utilities.hyphen_to_dash (volume)}, lower); else return wrap_msg ('issue', {sepc, issue}, lower); end end --[[-------------------------< F O R M A T _ P A G E S _ S H E E T S >----------------------------------------- adds static text to one of |page(s)= or |sheet(s)= values and returns it with all of the others set to empty strings. The return order is: page, pages, sheet, sheets Singular has priority over plural when both are provided. ]] local function format_pages_sheets (page, pages, sheet, sheets, cite_class, origin, sepc, nopp, lower) if 'map' == cite_class then -- only cite map supports sheet(s) as in-source locators if utilities.is_set (sheet) then if 'journal' == origin then return '', '', wrap_msg ('j-sheet', sheet, lower), ''; else return '', '', wrap_msg ('sheet', {sepc, sheet}, lower), ''; end elseif utilities.is_set (sheets) then if 'journal' == origin then return '', '', '', wrap_msg ('j-sheets', sheets, lower); else return '', '', '', wrap_msg ('sheets', {sepc, sheets}, lower); end end end local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin); if utilities.is_set (page) then if is_journal then return utilities.substitute (cfg.messages['j-page(s)'], page), '', '', ''; elseif not nopp then return utilities.substitute (cfg.messages['p-prefix'], {sepc, page}), '', '', ''; else return utilities.substitute (cfg.messages['nopp'], {sepc, page}), '', '', ''; end elseif utilities.is_set (pages) then if is_journal then return utilities.substitute (cfg.messages['j-page(s)'], pages), '', '', ''; elseif tonumber(pages) ~= nil and not nopp then -- if pages is only digits, assume a single page number return '', utilities.substitute (cfg.messages['p-prefix'], {sepc, pages}), '', ''; elseif not nopp then return '', utilities.substitute (cfg.messages['pp-prefix'], {sepc, pages}), '', ''; else return '', utilities.substitute (cfg.messages['nopp'], {sepc, pages}), '', ''; end end return '', '', '', ''; -- return empty strings end --[[--------------------------< I N S O U R C E _ L O C _ G E T >---------------------------------------------- returns one of the in-source locators: page, pages, or at. If any of these are interwiki links to Wikisource, returns the label portion of the interwiki-link as plain text for use in COinS. This COinS thing is done because here we convert an interwiki-link to an external link and add an icon span around that; get_coins_pages() doesn't know about the span. TODO: should it? TODO: add support for sheet and sheets?; streamline; TODO: make it so that this function returns only one of the three as the single in-source (the return value assigned to a new name)? ]] local function insource_loc_get (page, page_orig, pages, pages_orig, at) local ws_url, ws_label, coins_pages, L; -- for Wikisource interwiki-links; TODO: this corrupts page metadata (span remains in place after cleanup; fix there?) if utilities.is_set (page) then if utilities.is_set (pages) or utilities.is_set (at) then pages = ''; -- unset the others at = ''; end extra_text_in_page_check (page, page_orig); -- emit error message when |page= value begins with what looks like p., pp., etc. ws_url, ws_label, L = wikisource_url_make (page); -- make ws URL from |page= interwiki link; link portion L becomes tooltip label if ws_url then page = external_link (ws_url, ws_label .. '&nbsp;', 'ws link in page'); -- space char after label to move icon away from in-source text; TODO: a better way to do this? page = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, page}); coins_pages = ws_label; end elseif utilities.is_set (pages) then if utilities.is_set (at) then at = ''; -- unset end extra_text_in_page_check (pages, pages_orig); -- emit error message when |page= value begins with what looks like p., pp., etc. ws_url, ws_label, L = wikisource_url_make (pages); -- make ws URL from |pages= interwiki link; link portion L becomes tooltip label if ws_url then pages = external_link (ws_url, ws_label .. '&nbsp;', 'ws link in pages'); -- space char after label to move icon away from in-source text; TODO: a better way to do this? pages = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, pages}); coins_pages = ws_label; end elseif utilities.is_set (at) then ws_url, ws_label, L = wikisource_url_make (at); -- make ws URL from |at= interwiki link; link portion L becomes tooltip label if ws_url then at = external_link (ws_url, ws_label .. '&nbsp;', 'ws link in at'); -- space char after label to move icon away from in-source text; TODO: a better way to do this? at = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, at}); coins_pages = ws_label; end end return page, pages, at, coins_pages; end --[[--------------------------< I S _ U N I Q U E _ A R C H I V E _ U R L >------------------------------------ add error message when |archive-url= value is same as |url= or chapter-url= (or alias...) value ]] local function is_unique_archive_url (archive, url, c_url, source, date) if utilities.is_set (archive) then if archive == url or archive == c_url then utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); -- add error message return '', ''; -- unset |archive-url= and |archive-date= because same as |url= or |chapter-url= end end return archive, date; end --[=[-------------------------< A R C H I V E _ U R L _ C H E C K >-------------------------------------------- Check archive.org URLs to make sure they at least look like they are pointing at valid archives and not to the save snapshot URL or to calendar pages. When the archive URL is 'https://web.archive.org/save/' (or http://...) archive.org saves a snapshot of the target page in the URL. That is something that Wikipedia should not allow unwitting readers to do. When the archive.org URL does not have a complete timestamp, archive.org chooses a snapshot according to its own algorithm or provides a calendar 'search' result. [[WP:ELNO]] discourages links to search results. This function looks at the value assigned to |archive-url= and returns empty strings for |archive-url= and |archive-date= and an error message when: |archive-url= holds an archive.org save command URL |archive-url= is an archive.org URL that does not have a complete timestamp (YYYYMMDDhhmmss 14 digits) in the correct place otherwise returns |archive-url= and |archive-date= There are two mostly compatible archive.org URLs: //web.archive.org/<timestamp>... -- the old form //web.archive.org/web/<timestamp>... -- the new form The old form does not support or map to the new form when it contains a display flag. There are four identified flags ('id_', 'js_', 'cs_', 'im_') but since archive.org ignores others following the same form (two letters and an underscore) we don't check for these specific flags but we do check the form. This function supports a preview mode. When the article is rendered in preview mode, this function may return a modified archive URL: for save command errors, return undated wildcard (/*/) for timestamp errors when the timestamp has a wildcard, return the URL unmodified for timestamp errors when the timestamp does not have a wildcard, return with timestamp limited to six digits plus wildcard (/yyyymm*/) A secondary function is to return an archive-url timestamp from those urls that have them (archive.org and archive.today). The timestamp is used by validation.archive_date_check() to see if the value in |archive-date= matches the timestamp in the archive url. ]=] local function archive_url_check (url, date) local err_msg = ''; -- start with the error message empty local path, timestamp, flag; -- portions of the archive.org URL timestamp = url:match ('//archive.today/(%d%d%d%d%d%d%d%d%d%d%d%d%d%d)/'); -- get timestamp from archive.today urls if timestamp then -- if this was an archive.today url ... return url, date, timestamp; -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url=, and done end -- here for archive.org urls if (not url:match('//web%.archive%.org/')) and (not url:match('//liveweb%.archive%.org/')) then -- also deprecated liveweb Wayback machine URL return url, date; -- not an archive.org archive, return ArchiveURL and ArchiveDate end if url:match('//web%.archive%.org/save/') then -- if a save command URL, we don't want to allow saving of the target page err_msg = cfg.err_msg_supl.save; url = url:gsub ('(//web%.archive%.org)/save/', '%1/*/', 1); -- for preview mode: modify ArchiveURL elseif url:match('//liveweb%.archive%.org/') then err_msg = cfg.err_msg_supl.liveweb; else path, timestamp, flag = url:match('//web%.archive%.org/([^%d]*)(%d+)([^/]*)/'); -- split out some of the URL parts for evaluation if not path then -- malformed in some way; pattern did not match err_msg = cfg.err_msg_supl.timestamp; elseif 14 ~= timestamp:len() then -- path and flag optional, must have 14-digit timestamp here err_msg = cfg.err_msg_supl.timestamp; if '*' ~= flag then local replacement = timestamp:match ('^%d%d%d%d%d%d') or timestamp:match ('^%d%d%d%d'); -- get the first 6 (YYYYMM) or first 4 digits (YYYY) if replacement then -- nil if there aren't at least 4 digits (year) replacement = replacement .. string.rep ('0', 14 - replacement:len()); -- year or yearmo (4 or 6 digits) zero-fill to make 14-digit timestamp url=url:gsub ('(//web%.archive%.org/[^%d]*)%d[^/]*', '%1' .. replacement .. '*', 1) -- for preview, modify ts to 14 digits plus splat for calendar display end end elseif utilities.is_set (path) and 'web/' ~= path then -- older archive URLs do not have the extra 'web/' path element err_msg = cfg.err_msg_supl.path; elseif utilities.is_set (flag) and not utilities.is_set (path) then -- flag not allowed with the old form URL (without the 'web/' path element) err_msg = cfg.err_msg_supl.flag; elseif utilities.is_set (flag) and not flag:match ('%a%a_') then -- flag if present must be two alpha characters and underscore (requires 'web/' path element) err_msg = cfg.err_msg_supl.flag; else return url, date, timestamp; -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url= end end -- if here, something not right so utilities.set_message ('err_archive_url', {err_msg}); -- add error message and if is_preview_mode then return url, date, timestamp; -- preview mode so return ArchiveURL, ArchiveDate, and timestamp from |archive-url= else return '', ''; -- return empty strings for ArchiveURL and ArchiveDate end end --[[--------------------------< P L A C E _ C H E C K >-------------------------------------------------------- check |place=, |publication-place=, |location= to see if these params include digits. This function added because many editors misuse location to specify the in-source location (|page(s)= and |at= are supposed to do that) returns the original parameter value without modification; added maint cat when parameter value contains digits ]] local function place_check (param_val) if not utilities.is_set (param_val) then -- parameter empty or omitted return param_val; -- return that empty state end if mw.ustring.find (param_val, '%d') then -- not empty, are there digits in the parameter value utilities.set_message ('maint_location'); -- yep, add maint cat end return param_val; -- and done end --[[--------------------------< I S _ A R C H I V E D _ C O P Y >---------------------------------------------- compares |title= to 'Archived copy' (placeholder added by bots that can't find proper title); if matches, return true; nil else ]] local function is_archived_copy (title) title = mw.ustring.lower(title); -- switch title to lower case if title:find (cfg.special_case_translation.archived_copy.en) then -- if title is 'Archived copy' return true; elseif cfg.special_case_translation.archived_copy['local'] then if mw.ustring.find (title, cfg.special_case_translation.archived_copy['local']) then -- mw.ustring() because might not be Latin script return true; end end end --[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------ This is the main function doing the majority of the citation formatting. ]] local function citation0( config, args ) --[[ Load Input Parameters The argument_wrapper facilitates the mapping of multiple aliases to single internal variable. ]] local A = argument_wrapper ( args ); local i -- Pick out the relevant fields from the arguments. Different citation templates -- define different field names for the same underlying things. local author_etal; local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors= local Authors; local NameListStyle; if cfg.global_cs1_config_t['NameListStyle'] then -- global setting in {{cs1 config}} overrides local |name-list-style= parameter value; nil when empty or assigned value invalid NameListStyle = is_valid_parameter_value (cfg.global_cs1_config_t['NameListStyle'], 'cs1 config: name-list-style', cfg.keywords_lists['name-list-style'], ''); -- error messaging 'param' here is a hoax else NameListStyle = is_valid_parameter_value (A['NameListStyle'], A:ORIGIN('NameListStyle'), cfg.keywords_lists['name-list-style'], ''); end if cfg.global_cs1_config_t['NameListStyle'] and utilities.is_set (A['NameListStyle']) then -- when template has |name-list-style=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end local Collaboration = A['Collaboration']; do -- to limit scope of selected local selected = select_author_editor_source (A['Vauthors'], A['Authors'], args, 'AuthorList'); if 1 == selected then a, author_etal = extract_names (args, 'AuthorList'); -- fetch author list from |authorn= / |lastn= / |firstn=, |author-linkn=, and |author-maskn= elseif 2 == selected then NameListStyle = 'vanc'; -- override whatever |name-list-style= might be a, author_etal = parse_vauthors_veditors (args, A['Vauthors'], 'AuthorList'); -- fetch author list from |vauthors=, |author-linkn=, and |author-maskn= elseif 3 == selected then Authors = A['Authors']; -- use content of |authors= if 'authors' == A:ORIGIN('Authors') then -- but add a maint cat if the parameter is |authors= utilities.set_message ('maint_authors'); -- because use of this parameter is discouraged; what to do about the aliases is a TODO: end end if utilities.is_set (Collaboration) then author_etal = true; -- so that |display-authors=etal not required end end local editor_etal; local e = {}; -- editors list from |editor-lastn= / |editor-firstn= pairs or |veditors= do -- to limit scope of selected local selected = select_author_editor_source (A['Veditors'], nil, args, 'EditorList'); -- support for |editors= withdrawn if 1 == selected then e, editor_etal = extract_names (args, 'EditorList'); -- fetch editor list from |editorn= / |editor-lastn= / |editor-firstn=, |editor-linkn=, and |editor-maskn= elseif 2 == selected then NameListStyle = 'vanc'; -- override whatever |name-list-style= might be e, editor_etal = parse_vauthors_veditors (args, args.veditors, 'EditorList'); -- fetch editor list from |veditors=, |editor-linkn=, and |editor-maskn= end end local Chapter = A['Chapter']; -- done here so that we have access to |contribution= from |chapter= aliases local Chapter_origin = A:ORIGIN ('Chapter'); local Contribution; -- because contribution is required for contributor(s) if 'contribution' == Chapter_origin then Contribution = Chapter; -- get the name of the contribution end local c = {}; -- contributors list from |contributor-lastn= / contributor-firstn= pairs if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (A['Periodical']) then -- |contributor= and |contribution= only supported in book cites c = extract_names (args, 'ContributorList'); -- fetch contributor list from |contributorn= / |contributor-lastn=, -firstn=, -linkn=, -maskn= if 0 < #c then if not utilities.is_set (Contribution) then -- |contributor= requires |contribution= utilities.set_message ('err_contributor_missing_required_param', 'contribution'); -- add missing contribution error message c = {}; -- blank the contributors' table; it is used as a flag later end if 0 == #a then -- |contributor= requires |author= utilities.set_message ('err_contributor_missing_required_param', 'author'); -- add missing author error message c = {}; -- blank the contributors' table; it is used as a flag later end end else -- if not a book cite if utilities.select_one (args, cfg.aliases['ContributorList-Last'], 'err_redundant_parameters', 1 ) then -- are there contributor name list parameters? utilities.set_message ('err_contributor_ignored'); -- add contributor ignored error message end Contribution = nil; -- unset end local Title = A['Title']; local TitleLink = A['TitleLink']; local auto_select = ''; -- default is auto local accept_link; TitleLink, accept_link = utilities.has_accept_as_written (TitleLink, true); -- test for accept-this-as-written markup if (not accept_link) and utilities.in_array (TitleLink, {'none', 'pmc', 'doi'}) then -- check for special keywords auto_select = TitleLink; -- remember selection for later TitleLink = ''; -- treat as if |title-link= would have been empty end TitleLink = link_title_ok (TitleLink, A:ORIGIN ('TitleLink'), Title, 'title'); -- check for wiki-markup in |title-link= or wiki-markup in |title= when |title-link= is set local Section = ''; -- {{cite map}} only; preset to empty string for concatenation if not used if 'map' == config.CitationClass and 'section' == Chapter_origin then Section = A['Chapter']; -- get |section= from |chapter= alias list; |chapter= and the other aliases not supported in {{cite map}} Chapter = ''; -- unset for now; will be reset later from |map= if present end local Periodical = A['Periodical']; local Periodical_origin = A:ORIGIN('Periodical'); local ScriptPeriodical = A['ScriptPeriodical']; local ScriptPeriodical_origin = A:ORIGIN('ScriptPeriodical'); local TransPeriodical = A['TransPeriodical']; local TransPeriodical_origin = A:ORIGIN ('TransPeriodical'); if (utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (ScriptPeriodical))) then local param; if utilities.is_set (Periodical) then -- get a parameter name from one of these periodical related meta-parameters Periodical = nil; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters param = Periodical_origin -- get parameter name for error messaging elseif utilities.is_set (TransPeriodical) then TransPeriodical = nil; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters param = TransPeriodical_origin; -- get parameter name for error messaging elseif utilities.is_set (ScriptPeriodical) then ScriptPeriodical = nil; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters param = ScriptPeriodical_origin; -- get parameter name for error messaging end if utilities.is_set (param) then -- if we found one utilities.set_message ('err_periodical_ignored', {param}); -- emit an error message end end if utilities.is_set (Periodical) then local i; Periodical, i = utilities.strip_apostrophe_markup (Periodical); -- strip apostrophe markup so that metadata isn't contaminated if i then -- non-zero when markup was stripped so emit an error message utilities.set_message ('err_apostrophe_markup', {Periodical_origin}); end end if 'mailinglist' == config.CitationClass then -- special case for {{cite mailing list}} if utilities.is_set (Periodical) and utilities.is_set (A ['MailingList']) then -- both set emit an error TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', Periodical_origin) .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'mailinglist')}); end Periodical = A ['MailingList']; -- error or no, set Periodical to |mailinglist= value because this template is {{cite mailing list}} Periodical_origin = A:ORIGIN('MailingList'); end -- web and news not tested for now because of -- Wikipedia:Administrators%27_noticeboard#Is_there_a_semi-automated_tool_that_could_fix_these_annoying_"Cite_Web"_errors? if not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) then -- 'periodical' templates require periodical parameter -- local p = {['journal'] = 'journal', ['magazine'] = 'magazine', ['news'] = 'newspaper', ['web'] = 'website'}; -- for error message local p = {['journal'] = 'journal', ['magazine'] = 'magazine'}; -- for error message if p[config.CitationClass] then utilities.set_message ('err_missing_periodical', {config.CitationClass, p[config.CitationClass]}); end end local Volume; -- local ScriptPeriodical_origin = A:ORIGIN('ScriptPeriodical'); if 'citation' == config.CitationClass then if utilities.is_set (Periodical) then if not utilities.in_array (Periodical_origin, cfg.citation_no_volume_t) then -- {{citation}} does not render |volume= when these parameters are used Volume = A['Volume']; -- but does for all other 'periodicals' end elseif utilities.is_set (ScriptPeriodical) then if 'script-website' ~= ScriptPeriodical_origin then -- {{citation}} does not render volume for |script-website= Volume = A['Volume']; -- but does for all other 'periodicals' end else Volume = A['Volume']; -- and does for non-'periodical' cites end elseif utilities.in_array (config.CitationClass, cfg.templates_using_volume) then -- render |volume= for cs1 according to the configuration settings Volume = A['Volume']; end extra_text_in_vol_iss_check (Volume, A:ORIGIN ('Volume'), 'v'); local Issue; if 'citation' == config.CitationClass then if utilities.is_set (Periodical) and utilities.in_array (Periodical_origin, cfg.citation_issue_t) then -- {{citation}} may render |issue= when these parameters are used Issue = utilities.hyphen_to_dash (A['Issue']); end elseif utilities.in_array (config.CitationClass, cfg.templates_using_issue) then -- conference & map books do not support issue; {{citation}} listed here because included in settings table if not (utilities.in_array (config.CitationClass, {'conference', 'map', 'citation'}) and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then Issue = utilities.hyphen_to_dash (A['Issue']); end end local ArticleNumber; if utilities.in_array (config.CitationClass, {'journal', 'conference'}) or ('citation' == config.CitationClass and utilities.is_set (Periodical) and 'journal' == Periodical_origin) then ArticleNumber = A['ArticleNumber']; end extra_text_in_vol_iss_check (Issue, A:ORIGIN ('Issue'), 'i'); local Page; local Pages; local At; local QuotePage; local QuotePages; if not utilities.in_array (config.CitationClass, cfg.templates_not_using_page) then -- TODO: rewrite to emit ignored parameter error message? Page = A['Page']; Pages = utilities.hyphen_to_dash (A['Pages']); At = A['At']; QuotePage = A['QuotePage']; QuotePages = utilities.hyphen_to_dash (A['QuotePages']); end local Edition = A['Edition']; local PublicationPlace = place_check (A['PublicationPlace'], A:ORIGIN('PublicationPlace')); local Place = place_check (A['Place'], A:ORIGIN('Place')); local PublisherName = A['PublisherName']; local PublisherName_origin = A:ORIGIN('PublisherName'); if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then local i = 0; PublisherName, i = utilities.strip_apostrophe_markup (PublisherName); -- strip apostrophe markup so that metadata isn't contaminated; publisher is never italicized if i and (0 < i) then -- non-zero when markup was stripped so emit an error message utilities.set_message ('err_apostrophe_markup', {PublisherName_origin}); end end if ('document' == config.CitationClass) and not utilities.is_set (PublisherName) then utilities.set_message ('err_missing_publisher', {config.CitationClass, 'publisher'}); end local Newsgroup = A['Newsgroup']; -- TODO: strip apostrophe markup? local Newsgroup_origin = A:ORIGIN('Newsgroup'); if 'newsgroup' == config.CitationClass then if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then -- general use parameter |publisher= not allowed in cite newsgroup utilities.set_message ('err_parameter_ignored', {PublisherName_origin}); end PublisherName = nil; -- ensure that this parameter is unset for the time being; will be used again after COinS end local URL = A['URL']; -- TODO: better way to do this for URL, ChapterURL, and MapURL? local UrlAccess = is_valid_parameter_value (A['UrlAccess'], A:ORIGIN('UrlAccess'), cfg.keywords_lists['url-access'], nil); if not utilities.is_set (URL) and utilities.is_set (UrlAccess) then UrlAccess = nil; utilities.set_message ('err_param_access_requires_param', 'url'); end local ChapterURL = A['ChapterURL']; local ChapterUrlAccess = is_valid_parameter_value (A['ChapterUrlAccess'], A:ORIGIN('ChapterUrlAccess'), cfg.keywords_lists['url-access'], nil); if not utilities.is_set (ChapterURL) and utilities.is_set (ChapterUrlAccess) then ChapterUrlAccess = nil; utilities.set_message ('err_param_access_requires_param', {A:ORIGIN('ChapterUrlAccess'):gsub ('%-access', '')}); end local MapUrlAccess = is_valid_parameter_value (A['MapUrlAccess'], A:ORIGIN('MapUrlAccess'), cfg.keywords_lists['url-access'], nil); if not utilities.is_set (A['MapURL']) and utilities.is_set (MapUrlAccess) then MapUrlAccess = nil; utilities.set_message ('err_param_access_requires_param', {'map-url'}); end local this_page = mw.title.getCurrentTitle(); -- also used for COinS and for language local no_tracking_cats = is_valid_parameter_value (A['NoTracking'], A:ORIGIN('NoTracking'), cfg.keywords_lists['yes_true_y'], nil); -- check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories if not utilities.is_set (no_tracking_cats) then -- ignore if we are already not going to categorize this page if cfg.uncategorized_namespaces[this_page.namespace] then -- is this page's namespace id one of the uncategorized namespace ids? no_tracking_cats = "true"; -- set no_tracking_cats end for _, v in ipairs (cfg.uncategorized_subpages) do -- cycle through page name patterns if this_page.text:match (v) then -- test page name against each pattern no_tracking_cats = "true"; -- set no_tracking_cats break; -- bail out if one is found end end end -- check for extra |page=, |pages= or |at= parameters. (also sheet and sheets while we're at it) utilities.select_one (args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'err_redundant_parameters'); -- this is a dummy call simply to get the error message and category local coins_pages; Page, Pages, At, coins_pages = insource_loc_get (Page, A:ORIGIN('Page'), Pages, A:ORIGIN('Pages'), At); local NoPP = is_valid_parameter_value (A['NoPP'], A:ORIGIN('NoPP'), cfg.keywords_lists['yes_true_y'], nil); if utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- both |publication-place= and |place= (|location=) allowed if different utilities.add_prop_cat ('location-test'); -- add property cat to evaluate how often PublicationPlace and Place are used together if PublicationPlace == Place then Place = ''; -- unset; don't need both if they are the same end elseif not utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- when only |place= (|location=) is set ... PublicationPlace = Place; -- promote |place= (|location=) to |publication-place end if PublicationPlace == Place then Place = ''; end -- don't need both if they are the same local URL_origin = A:ORIGIN('URL'); -- get name of parameter that holds URL local ChapterURL_origin = A:ORIGIN('ChapterURL'); -- get name of parameter that holds ChapterURL local ScriptChapter = A['ScriptChapter']; local ScriptChapter_origin = A:ORIGIN ('ScriptChapter'); local Format = A['Format']; local ChapterFormat = A['ChapterFormat']; local TransChapter = A['TransChapter']; local TransChapter_origin = A:ORIGIN ('TransChapter'); local TransTitle = A['TransTitle']; local ScriptTitle = A['ScriptTitle']; --[[ Parameter remapping for cite encyclopedia: When the citation has these parameters: |encyclopedia= and |title= then map |title= to |article= and |encyclopedia= to |title= for rendering |encyclopedia= and |article= then map |encyclopedia= to |title= for rendering |trans-title= maps to |trans-chapter= when |title= is re-mapped |url= maps to |chapter-url= when |title= is remapped All other combinations of |encyclopedia=, |title=, and |article= are not modified ]] local Encyclopedia = A['Encyclopedia']; -- used as a flag by this module and by ~/COinS if utilities.is_set (Encyclopedia) then -- emit error message when Encyclopedia set but template is other than {{cite encyclopedia}} or {{citation}} if 'encyclopaedia' ~= config.CitationClass and 'citation' ~= config.CitationClass then utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('Encyclopedia')}); Encyclopedia = nil; -- unset because not supported by this template end end if ('encyclopaedia' == config.CitationClass) or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then if utilities.is_set (Periodical) and utilities.is_set (Encyclopedia) then -- when both parameters set emit an error message; {{citation}} only; Periodical not allowed in {{cite encyclopedia}} utilities.set_message ('err_periodical_ignored', {Periodical_origin}); end if utilities.is_set (Encyclopedia) then Periodical = Encyclopedia; -- error or no, set Periodical to Encyclopedia for rendering; {{citation}} could (not legitimately) have both; use Encyclopedia Periodical_origin = A:ORIGIN ('Encyclopedia'); if utilities.is_set (Title) or utilities.is_set (ScriptTitle) then if not utilities.is_set (Chapter) then Chapter = Title; -- |encyclopedia= and |title= are set so map |title= to |article= and |encyclopedia= to |title= for rendering ScriptChapter = ScriptTitle; ScriptChapter_origin = A:ORIGIN('ScriptTitle') TransChapter = TransTitle; ChapterURL = URL; ChapterURL_origin = URL_origin; ChapterUrlAccess = UrlAccess; if not utilities.is_set (ChapterURL) and utilities.is_set (TitleLink) then Chapter = utilities.make_wikilink (TitleLink, Chapter); end Title = Periodical; ChapterFormat = Format; Periodical = ''; -- redundant so unset TransTitle = ''; URL = ''; Format = ''; TitleLink = ''; ScriptTitle = ''; end elseif utilities.is_set (Chapter) or utilities.is_set (ScriptChapter) then -- |title= not set Title = Periodical; -- |encyclopedia= set and |article= set so map |encyclopedia= to |title= for rendering Periodical = ''; -- redundant so unset end end end -- special case for cite techreport. local ID = A['ID']; if (config.CitationClass == "techreport") then -- special case for cite techreport if utilities.is_set (A['Number']) then -- cite techreport uses 'number', which other citations alias to 'issue' if not utilities.is_set (ID) then -- can we use ID for the "number"? ID = A['Number']; -- yes, use it else -- ID has a value so emit error message utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'id') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'number')}); end end end -- Account for the oddity that is {{cite conference}}, before generation of COinS data. local ChapterLink -- = A['ChapterLink']; -- deprecated as a parameter but still used internally by cite episode local Conference = A['Conference']; local BookTitle = A['BookTitle']; local TransTitle_origin = A:ORIGIN ('TransTitle'); if 'conference' == config.CitationClass then if utilities.is_set (BookTitle) then Chapter = Title; Chapter_origin = 'title'; -- ChapterLink = TitleLink; -- |chapter-link= is deprecated ChapterURL = URL; ChapterUrlAccess = UrlAccess; ChapterURL_origin = URL_origin; URL_origin = ''; ChapterFormat = Format; TransChapter = TransTitle; TransChapter_origin = TransTitle_origin; Title = BookTitle; Format = ''; -- TitleLink = ''; TransTitle = ''; URL = ''; end elseif 'speech' ~= config.CitationClass then Conference = ''; -- not cite conference or cite speech so make sure this is empty string end -- CS1/2 mode local Mode; if cfg.global_cs1_config_t['Mode'] then -- global setting in {{cs1 config}} overrides local |mode= parameter value; nil when empty or assigned value invalid Mode = is_valid_parameter_value (cfg.global_cs1_config_t['Mode'], 'cs1 config: mode', cfg.keywords_lists['mode'], ''); -- error messaging 'param' here is a hoax else Mode = is_valid_parameter_value (A['Mode'], A:ORIGIN('Mode'), cfg.keywords_lists['mode'], ''); end if cfg.global_cs1_config_t['Mode'] and utilities.is_set (A['Mode']) then -- when template has |mode=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end -- separator character and postscript local sepc, PostScript = set_style (Mode:lower(), A['PostScript'], config.CitationClass); -- controls capitalization of certain static text local use_lowercase = ( sepc == ',' ); -- cite map oddities local Cartography = ""; local Scale = ""; local Sheet = A['Sheet'] or ''; local Sheets = A['Sheets'] or ''; if config.CitationClass == "map" then if utilities.is_set (Chapter) then --TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'map') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', Chapter_origin)}); -- add error message end Chapter = A['Map']; Chapter_origin = A:ORIGIN('Map'); ChapterURL = A['MapURL']; ChapterURL_origin = A:ORIGIN('MapURL'); TransChapter = A['TransMap']; ScriptChapter = A['ScriptMap'] ScriptChapter_origin = A:ORIGIN('ScriptMap') ChapterUrlAccess = MapUrlAccess; ChapterFormat = A['MapFormat']; Cartography = A['Cartography']; if utilities.is_set ( Cartography ) then Cartography = sepc .. " " .. wrap_msg ('cartography', Cartography, use_lowercase); end Scale = A['Scale']; if utilities.is_set ( Scale ) then Scale = sepc .. " " .. Scale; end end -- Account for the oddities that are {{cite episode}} and {{cite serial}}, before generation of COinS data. local Series = A['Series']; if 'episode' == config.CitationClass or 'serial' == config.CitationClass then local SeriesLink = A['SeriesLink']; SeriesLink = link_title_ok (SeriesLink, A:ORIGIN ('SeriesLink'), Series, 'series'); -- check for wiki-markup in |series-link= or wiki-markup in |series= when |series-link= is set local Network = A['Network']; local Station = A['Station']; local s, n = {}, {}; -- do common parameters first if utilities.is_set (Network) then table.insert(n, Network); end if utilities.is_set (Station) then table.insert(n, Station); end ID = table.concat(n, sepc .. ' '); if 'episode' == config.CitationClass then -- handle the oddities that are strictly {{cite episode}} local Season = A['Season']; local SeriesNumber = A['SeriesNumber']; if utilities.is_set (Season) and utilities.is_set (SeriesNumber) then -- these are mutually exclusive so if both are set TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'season') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'seriesno')}); -- add error message SeriesNumber = ''; -- unset; prefer |season= over |seriesno= end -- assemble a table of parts concatenated later into Series if utilities.is_set (Season) then table.insert(s, wrap_msg ('season', Season, use_lowercase)); end if utilities.is_set (SeriesNumber) then table.insert(s, wrap_msg ('seriesnum', SeriesNumber, use_lowercase)); end if utilities.is_set (Issue) then table.insert(s, wrap_msg ('episode', Issue, use_lowercase)); end Issue = ''; -- unset because this is not a unique parameter Chapter = Title; -- promote title parameters to chapter ScriptChapter = ScriptTitle; ScriptChapter_origin = A:ORIGIN('ScriptTitle'); ChapterLink = TitleLink; -- alias |episode-link= TransChapter = TransTitle; ChapterURL = URL; ChapterUrlAccess = UrlAccess; ChapterURL_origin = URL_origin; ChapterFormat = Format; Title = Series; -- promote series to title TitleLink = SeriesLink; Series = table.concat(s, sepc .. ' '); -- this is concatenation of season, seriesno, episode number if utilities.is_set (ChapterLink) and not utilities.is_set (ChapterURL) then -- link but not URL Chapter = utilities.make_wikilink (ChapterLink, Chapter); elseif utilities.is_set (ChapterLink) and utilities.is_set (ChapterURL) then -- if both are set, URL links episode; Series = utilities.make_wikilink (ChapterLink, Series); end URL = ''; -- unset TransTitle = ''; ScriptTitle = ''; Format = ''; else -- now oddities that are cite serial Issue = ''; -- unset because this parameter no longer supported by the citation/core version of cite serial Chapter = A['Episode']; -- TODO: make |episode= available to cite episode someday? if utilities.is_set (Series) and utilities.is_set (SeriesLink) then Series = utilities.make_wikilink (SeriesLink, Series); end Series = utilities.wrap_style ('italic-title', Series); -- series is italicized end end -- end of {{cite episode}} stuff -- handle type parameter for those CS1 citations that have default values local TitleType = A['TitleType']; local Degree = A['Degree']; if utilities.in_array (config.CitationClass, {'AV-media-notes', 'document', 'interview', 'mailinglist', 'map', 'podcast', 'pressrelease', 'report', 'speech', 'techreport', 'thesis'}) then TitleType = set_titletype (config.CitationClass, TitleType); if utilities.is_set (Degree) and "Thesis" == TitleType then -- special case for cite thesis TitleType = Degree .. ' ' .. cfg.title_types ['thesis']:lower(); end end if utilities.is_set (TitleType) then -- if type parameter is specified TitleType = utilities.substitute ( cfg.messages['type'], TitleType); -- display it in parentheses -- TODO: Hack on TitleType to fix bunched parentheses problem end -- legacy: promote PublicationDate to Date if neither Date nor Year are set. local Date = A['Date']; local Date_origin; -- to hold the name of parameter promoted to Date; required for date error messaging local PublicationDate = A['PublicationDate']; local Year = A['Year']; if not utilities.is_set (Date) then Date = Year; -- promote Year to Date Year = nil; -- make nil so Year as empty string isn't used for CITEREF if not utilities.is_set (Date) and utilities.is_set (PublicationDate) then -- use PublicationDate when |date= and |year= are not set Date = PublicationDate; -- promote PublicationDate to Date PublicationDate = ''; -- unset, no longer needed Date_origin = A:ORIGIN('PublicationDate'); -- save the name of the promoted parameter else Date_origin = A:ORIGIN('Year'); -- save the name of the promoted parameter end else Date_origin = A:ORIGIN('Date'); -- not a promotion; name required for error messaging end if PublicationDate == Date then PublicationDate = ''; end -- if PublicationDate is same as Date, don't display in rendered citation --[[ Go test all of the date-holding parameters for valid MOS:DATE format and make sure that dates are real dates. This must be done before we do COinS because here is where we get the date used in the metadata. Date validation supporting code is in Module:Citation/CS1/Date_validation ]] local DF = is_valid_parameter_value (A['DF'], A:ORIGIN('DF'), cfg.keywords_lists['df'], ''); if not utilities.is_set (DF) then DF = cfg.global_df; -- local |df= if present overrides global df set by {{use xxx date}} template end local ArchiveURL; local ArchiveDate; local ArchiveFormat = A['ArchiveFormat']; local archive_url_timestamp; -- timestamp from wayback machine url ArchiveURL, ArchiveDate, archive_url_timestamp = archive_url_check (A['ArchiveURL'], A['ArchiveDate']) ArchiveFormat = style_format (ArchiveFormat, ArchiveURL, 'archive-format', 'archive-url'); ArchiveURL, ArchiveDate = is_unique_archive_url (ArchiveURL, URL, ChapterURL, A:ORIGIN('ArchiveURL'), ArchiveDate); -- add error message when URL or ChapterURL == ArchiveURL local AccessDate = A['AccessDate']; -- local LayDate = A['LayDate']; local COinS_date = {}; -- holds date info extracted from |date= for the COinS metadata by Module:Date verification local DoiBroken = A['DoiBroken']; local Embargo = A['Embargo']; local anchor_year; -- used in the CITEREF identifier do -- create defined block to contain local variables error_message, date_parameters_list, mismatch local error_message = ''; -- AirDate has been promoted to Date so not necessary to check it local date_parameters_list = { ['access-date'] = {val = AccessDate, name = A:ORIGIN ('AccessDate')}, ['archive-date'] = {val = ArchiveDate, name = A:ORIGIN ('ArchiveDate')}, ['date'] = {val = Date, name = Date_origin}, ['doi-broken-date'] = {val = DoiBroken, name = A:ORIGIN ('DoiBroken')}, ['pmc-embargo-date'] = {val = Embargo, name = A:ORIGIN ('Embargo')}, -- ['lay-date'] = {val = LayDate, name = A:ORIGIN ('LayDate')}, ['publication-date'] = {val = PublicationDate, name = A:ORIGIN ('PublicationDate')}, ['year'] = {val = Year, name = A:ORIGIN ('Year')}, }; local error_list = {}; anchor_year, Embargo = validation.dates(date_parameters_list, COinS_date, error_list); -- start temporary Julian / Gregorian calendar uncertainty categorization if COinS_date.inter_cal_cat then utilities.add_prop_cat ('jul-greg-uncertainty'); end -- end temporary Julian / Gregorian calendar uncertainty categorization if utilities.is_set (Year) and utilities.is_set (Date) then -- both |date= and |year= not normally needed; validation.year_date_check (Year, A:ORIGIN ('Year'), Date, A:ORIGIN ('Date'), error_list); end if 0 == #error_list then -- error free dates only; 0 when error_list is empty local modified = false; -- flag if utilities.is_set (DF) then -- if we need to reformat dates modified = validation.reformat_dates (date_parameters_list, DF); -- reformat to DF format, use long month names if appropriate end if true == validation.date_hyphen_to_dash (date_parameters_list) then -- convert hyphens to dashes where appropriate modified = true; utilities.set_message ('maint_date_format'); -- hyphens were converted so add maint category end -- for those wikis that can and want to have English date names translated to the local language; not supported at en.wiki if cfg.date_name_auto_xlate_enable and validation.date_name_xlate (date_parameters_list, cfg.date_digit_auto_xlate_enable ) then utilities.set_message ('maint_date_auto_xlated'); -- add maint cat modified = true; end if modified then -- if the date_parameters_list values were modified AccessDate = date_parameters_list['access-date'].val; -- overwrite date holding parameters with modified values ArchiveDate = date_parameters_list['archive-date'].val; Date = date_parameters_list['date'].val; DoiBroken = date_parameters_list['doi-broken-date'].val; -- LayDate = date_parameters_list['lay-date'].val; PublicationDate = date_parameters_list['publication-date'].val; end if archive_url_timestamp and utilities.is_set (ArchiveDate) then validation.archive_date_check (ArchiveDate, archive_url_timestamp); -- does YYYYMMDD in archive_url_timestamp match date in ArchiveDate end else utilities.set_message ('err_bad_date', {utilities.make_sep_list (#error_list, error_list)}); -- add this error message end end -- end of do if utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) or -- {{cite book}}, {{cite encyclopedia}}; TODO: {{cite conference}} and others? ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) or -- {{citation}} as an encylopedia citation ('citation' == config.CitationClass and not utilities.is_set (Periodical)) then -- {{citation}} as a book citation if utilities.is_set (PublicationPlace) then if not utilities.is_set (PublisherName) then local date = COinS_date.rftdate and tonumber (COinS_date.rftdate:match ('%d%d%d%d')); -- get year portion of COinS date (because in Arabic numerals); convert string to number if date and (1850 <= date) then -- location has no publisher; if date is 1850 or later utilities.set_message ('maint_location_no_publisher'); -- add maint cat end else -- PublisherName has a value if cfg.keywords_xlate['none'] == PublisherName then -- if that value is 'none' (only for book and encyclopedia citations) PublisherName = ''; -- unset end end end end local ID_list = {}; -- sequence table of rendered identifiers local ID_list_coins = {}; -- table of identifiers and their values from args; key is same as cfg.id_handlers's key local Class = A['Class']; -- arxiv class identifier local ID_support = { {A['ASINTLD'], 'ASIN', 'err_asintld_missing_asin', A:ORIGIN ('ASINTLD')}, {DoiBroken, 'DOI', 'err_doibroken_missing_doi', A:ORIGIN ('DoiBroken')}, {Embargo, 'PMC', 'err_embargo_missing_pmc', A:ORIGIN ('Embargo')}, } ID_list, ID_list_coins = identifiers.identifier_lists_get (args, {DoiBroken = DoiBroken, ASINTLD = A['ASINTLD'], Embargo = Embargo, Class = Class}, ID_support); -- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, {{cite ssrn}}, before generation of COinS data. if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- |arxiv= or |eprint= required for cite arxiv; |biorxiv=, |citeseerx=, |medrxiv=, |ssrn= required for their templates if not (args[cfg.id_handlers[config.CitationClass:upper()].parameters[1]] or -- can't use ID_list_coins k/v table here because invalid parameters omitted args[cfg.id_handlers[config.CitationClass:upper()].parameters[2]]) then -- which causes unexpected parameter missing error message utilities.set_message ('err_' .. config.CitationClass .. '_missing'); -- add error message end Periodical = ({['arxiv'] = 'arXiv', ['biorxiv'] = 'bioRxiv', ['citeseerx'] = 'CiteSeerX', ['medrxiv'] = 'medRxiv', ['ssrn'] = 'Social Science Research Network'})[config.CitationClass]; end -- Link the title of the work if no |url= was provided, but we have a |pmc= or a |doi= with |doi-access=free if config.CitationClass == "journal" and not utilities.is_set (URL) and not utilities.is_set (TitleLink) and not utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) then -- TODO: remove 'none' once existing citations have been switched to 'off', so 'none' can be used as token for "no title" instead if 'none' ~= cfg.keywords_xlate[auto_select] then -- if auto-linking not disabled if identifiers.auto_link_urls[auto_select] then -- manual selection URL = identifiers.auto_link_urls[auto_select]; -- set URL to be the same as identifier's external link URL_origin = cfg.id_handlers[auto_select:upper()].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title= elseif identifiers.auto_link_urls['pmc'] then -- auto-select PMC URL = identifiers.auto_link_urls['pmc']; -- set URL to be the same as the PMC external link if not embargoed URL_origin = cfg.id_handlers['PMC'].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title= elseif identifiers.auto_link_urls['doi'] then -- auto-select DOI URL = identifiers.auto_link_urls['doi']; URL_origin = cfg.id_handlers['DOI'].parameters[1]; end end if utilities.is_set (URL) then -- set when using an identifier-created URL if utilities.is_set (AccessDate) then -- |access-date= requires |url=; identifier-created URL is not |url= utilities.set_message ('err_accessdate_missing_url'); -- add an error message AccessDate = ''; -- unset end if utilities.is_set (ArchiveURL) then -- |archive-url= requires |url=; identifier-created URL is not |url= utilities.set_message ('err_archive_missing_url'); -- add an error message ArchiveURL = ''; -- unset end end end -- At this point fields may be nil if they weren't specified in the template use. We can use that fact. -- Test if citation has no title if not utilities.is_set (Title) and not utilities.is_set (TransTitle) and not utilities.is_set (ScriptTitle) then -- has special case for cite episode utilities.set_message ('err_citation_missing_title', {'episode' == config.CitationClass and 'series' or 'title'}); end if utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) and utilities.in_array (config.CitationClass, {'journal', 'citation'}) and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and ('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin) then -- special case for journal cites Title = ''; -- set title to empty string utilities.set_message ('maint_untitled'); -- add maint cat end -- COinS metadata (see <http://ocoins.info/>) for automated parsing of citation information. -- handle the oddity that is cite encyclopedia and {{citation |encyclopedia=something}}. Here we presume that -- when Periodical, Title, and Chapter are all set, then Periodical is the book (encyclopedia) title, Title -- is the article title, and Chapter is a section within the article. So, we remap local coins_chapter = Chapter; -- default assuming that remapping not required local coins_title = Title; -- et tu if 'encyclopaedia' == config.CitationClass or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then if utilities.is_set (Chapter) and utilities.is_set (Title) and utilities.is_set (Periodical) then -- if all are used then coins_chapter = Title; -- remap coins_title = Periodical; end end local coins_author = a; -- default for coins rft.au if 0 < #c then -- but if contributor list coins_author = c; -- use that instead end -- this is the function call to COinS() local OCinSoutput = metadata.COinS({ ['Periodical'] = utilities.strip_apostrophe_markup (Periodical), -- no markup in the metadata ['Encyclopedia'] = Encyclopedia, -- just a flag; content ignored by ~/COinS ['Chapter'] = metadata.make_coins_title (coins_chapter, ScriptChapter), -- Chapter and ScriptChapter stripped of bold / italic / accept-as-written markup ['Degree'] = Degree; -- cite thesis only ['Title'] = metadata.make_coins_title (coins_title, ScriptTitle), -- Title and ScriptTitle stripped of bold / italic / accept-as-written markup ['PublicationPlace'] = PublicationPlace, ['Date'] = COinS_date.rftdate, -- COinS_date.* has correctly formatted date values if Date is valid; ['Season'] = COinS_date.rftssn, ['Quarter'] = COinS_date.rftquarter, ['Chron'] = COinS_date.rftchron, ['Series'] = Series, ['Volume'] = Volume, ['Issue'] = Issue, ['ArticleNumber'] = ArticleNumber, ['Pages'] = coins_pages or metadata.get_coins_pages (first_set ({Sheet, Sheets, Page, Pages, At, QuotePage, QuotePages}, 7)), -- pages stripped of external links ['Edition'] = Edition, ['PublisherName'] = PublisherName or Newsgroup, -- any apostrophe markup already removed from PublisherName ['URL'] = first_set ({ChapterURL, URL}, 2), ['Authors'] = coins_author, ['ID_list'] = ID_list_coins, ['RawPage'] = this_page.prefixedText, }, config.CitationClass); -- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, and {{cite ssrn}} AFTER generation of COinS data. if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- we have set rft.jtitle in COinS to arXiv, bioRxiv, CiteSeerX, medRxiv, or ssrn now unset so it isn't displayed Periodical = ''; -- periodical not allowed in these templates; if article has been published, use cite journal end -- special case for cite newsgroup. Do this after COinS because we are modifying Publishername to include some static text if 'newsgroup' == config.CitationClass and utilities.is_set (Newsgroup) then PublisherName = utilities.substitute (cfg.messages['newsgroup'], external_link( 'news:' .. Newsgroup, Newsgroup, Newsgroup_origin, nil )); end local Editors; local EditorCount; -- used only for choosing {ed.) or (eds.) annotation at end of editor name-list local Contributors; -- assembled contributors name list local contributor_etal; local Translators; -- assembled translators name list local translator_etal; local t = {}; -- translators list from |translator-lastn= / translator-firstn= pairs t = extract_names (args, 'TranslatorList'); -- fetch translator list from |translatorn= / |translator-lastn=, -firstn=, -linkn=, -maskn= local Interviewers; local interviewers_list = {}; interviewers_list = extract_names (args, 'InterviewerList'); -- process preferred interviewers parameters local interviewer_etal; -- Now perform various field substitutions. -- We also add leading spaces and surrounding markup and punctuation to the -- various parts of the citation, but only when they are non-nil. do local last_first_list; local control = { format = NameListStyle, -- empty string, '&', 'amp', 'and', or 'vanc' maximum = nil, -- as if display-authors or display-editors not set mode = Mode }; do -- do editor name list first because the now unsupported coauthors used to modify control table if cfg.global_cs1_config_t['DisplayEditors'] then -- global setting from {{cs1 config}} overrides local setting control.maximum , editor_etal = get_display_names (cfg.global_cs1_config_t['DisplayEditors'], #e, 'editors', editor_etal, 'cs1 config'); else control.maximum , editor_etal = get_display_names (A['DisplayEditors'], #e, 'editors', editor_etal, A:ORIGIN ('DisplayEditors')); end if cfg.global_cs1_config_t['DisplayEditors'] and utilities.is_set (A['DisplayEditors']) then -- when template has |display-editors=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end Editors, EditorCount = list_people (control, e, editor_etal); if 1 == EditorCount and (true == editor_etal or 1 < #e) then -- only one editor displayed but includes etal then EditorCount = 2; -- spoof to display (eds.) annotation end end do -- now do interviewers if cfg.global_cs1_config_t['DisplayInterviewers'] then -- global setting from {{cs1 config}} overrides local setting control.maximum, interviewer_etal = get_display_names (cfg.global_cs1_config_t['DisplayInterviewers'], #interviewers_list, 'interviewers', interviewer_etal, 'cs1 config'); else control.maximum, interviewer_etal = get_display_names (A['DisplayInterviewers'], #interviewers_list, 'interviewers', interviewer_etal, A:ORIGIN ('DisplayInterviewers')); end if cfg.global_cs1_config_t['DisplayInterviewers'] and utilities.is_set (A['DisplayInterviewers']) then -- when template has |display-interviewers=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end Interviewers = list_people (control, interviewers_list, interviewer_etal); end do -- now do translators if cfg.global_cs1_config_t['DisplayTranslators'] then -- global setting from {{cs1 config}} overrides local setting control.maximum, translator_etal = get_display_names (cfg.global_cs1_config_t['DisplayTranslators'], #t, 'translators', translator_etal, 'cs1 config'); else control.maximum, translator_etal = get_display_names (A['DisplayTranslators'], #t, 'translators', translator_etal, A:ORIGIN ('DisplayTranslators')); end if cfg.global_cs1_config_t['DisplayTranslators'] and utilities.is_set (A['DisplayTranslators']) then -- when template has |display-translators=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end Translators = list_people (control, t, translator_etal); end do -- now do contributors if cfg.global_cs1_config_t['DisplayContributors'] then -- global setting from {{cs1 config}} overrides local setting control.maximum, contributor_etal = get_display_names (cfg.global_cs1_config_t['DisplayContributors'], #c, 'contributors', contributor_etal, 'cs1 config'); else control.maximum, contributor_etal = get_display_names (A['DisplayContributors'], #c, 'contributors', contributor_etal, A:ORIGIN ('DisplayContributors')); end if cfg.global_cs1_config_t['DisplayContributors'] and utilities.is_set (A['DisplayContributors']) then -- when template has |display-contributors=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end Contributors = list_people (control, c, contributor_etal); end do -- now do authors if cfg.global_cs1_config_t['DisplayAuthors'] then -- global setting from {{cs1 config}} overrides local setting control.maximum, author_etal = get_display_names (cfg.global_cs1_config_t['DisplayAuthors'], #a, 'authors', author_etal, 'cs1 config'); else control.maximum, author_etal = get_display_names (A['DisplayAuthors'], #a, 'authors', author_etal, A:ORIGIN ('DisplayAuthors')); end if cfg.global_cs1_config_t['DisplayAuthors'] and utilities.is_set (A['DisplayAuthors']) then -- when template has |display-authors=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end last_first_list = list_people (control, a, author_etal); if utilities.is_set (Authors) then Authors, author_etal = name_has_etal (Authors, author_etal, false, 'authors'); -- find and remove variations on et al. if author_etal then Authors = Authors .. ' ' .. cfg.messages['et al']; -- add et al. to authors parameter end else Authors = last_first_list; -- either an author name list or an empty string end end -- end of do if utilities.is_set (Authors) and utilities.is_set (Collaboration) then Authors = Authors .. ' (' .. Collaboration .. ')'; -- add collaboration after et al. end end local ConferenceFormat = A['ConferenceFormat']; local ConferenceURL = A['ConferenceURL']; ConferenceFormat = style_format (ConferenceFormat, ConferenceURL, 'conference-format', 'conference-url'); Format = style_format (Format, URL, 'format', 'url'); -- special case for chapter format so no error message or cat when chapter not supported if not (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia))) then ChapterFormat = style_format (ChapterFormat, ChapterURL, 'chapter-format', 'chapter-url'); end if not utilities.is_set (URL) then if utilities.in_array (config.CitationClass, {"web", "podcast", "mailinglist"}) or -- |url= required for cite web, cite podcast, and cite mailinglist ('citation' == config.CitationClass and ('website' == Periodical_origin or 'script-website' == ScriptPeriodical_origin)) then -- and required for {{citation}} with |website= or |script-website= utilities.set_message ('err_cite_web_url'); end -- do we have |accessdate= without either |url= or |chapter-url=? if utilities.is_set (AccessDate) and not utilities.is_set (ChapterURL) then -- ChapterURL may be set when URL is not set; utilities.set_message ('err_accessdate_missing_url'); AccessDate = ''; end end local UrlStatus = is_valid_parameter_value (A['UrlStatus'], A:ORIGIN('UrlStatus'), cfg.keywords_lists['url-status'], ''); local OriginalURL local OriginalURL_origin local OriginalFormat local OriginalAccess; UrlStatus = UrlStatus:lower(); -- used later when assembling archived text if utilities.is_set ( ArchiveURL ) then if utilities.is_set (ChapterURL) then -- if chapter-url= is set apply archive url to it OriginalURL = ChapterURL; -- save copy of source chapter's url for archive text OriginalURL_origin = ChapterURL_origin; -- name of |chapter-url= parameter for error messages OriginalFormat = ChapterFormat; -- and original |chapter-format= if 'live' ~= UrlStatus then ChapterURL = ArchiveURL -- swap-in the archive's URL ChapterURL_origin = A:ORIGIN('ArchiveURL') -- name of |archive-url= parameter for error messages ChapterFormat = ArchiveFormat or ''; -- swap in archive's format ChapterUrlAccess = nil; -- restricted access levels do not make sense for archived URLs end elseif utilities.is_set (URL) then OriginalURL = URL; -- save copy of original source URL OriginalURL_origin = URL_origin; -- name of URL parameter for error messages OriginalFormat = Format; -- and original |format= OriginalAccess = UrlAccess; if 'live' ~= UrlStatus then -- if URL set then |archive-url= applies to it URL = ArchiveURL -- swap-in the archive's URL URL_origin = A:ORIGIN('ArchiveURL') -- name of archive URL parameter for error messages Format = ArchiveFormat or ''; -- swap in archive's format UrlAccess = nil; -- restricted access levels do not make sense for archived URLs end end elseif utilities.is_set (UrlStatus) then -- if |url-status= is set when |archive-url= is not set utilities.set_message ('maint_url_status'); -- add maint cat end if utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or -- if any of the 'periodical' cites except encyclopedia ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) then local chap_param; if utilities.is_set (Chapter) then -- get a parameter name from one of these chapter related meta-parameters chap_param = A:ORIGIN ('Chapter') elseif utilities.is_set (TransChapter) then chap_param = A:ORIGIN ('TransChapter') elseif utilities.is_set (ChapterURL) then chap_param = A:ORIGIN ('ChapterURL') elseif utilities.is_set (ScriptChapter) then chap_param = ScriptChapter_origin; else utilities.is_set (ChapterFormat) chap_param = A:ORIGIN ('ChapterFormat') end if utilities.is_set (chap_param) then -- if we found one utilities.set_message ('err_chapter_ignored', {chap_param}); -- add error message Chapter = ''; -- and set them to empty string to be safe with concatenation TransChapter = ''; ChapterURL = ''; ScriptChapter = ''; ChapterFormat = ''; end else -- otherwise, format chapter / article title local no_quotes = false; -- default assume that we will be quoting the chapter parameter value if utilities.is_set (Contribution) and 0 < #c then -- if this is a contribution with contributor(s) if utilities.in_array (Contribution:lower(), cfg.keywords_lists.contribution) then -- and a generic contribution title no_quotes = true; -- then render it unquoted end end Chapter = format_chapter_title (ScriptChapter, ScriptChapter_origin, Chapter, Chapter_origin, TransChapter, TransChapter_origin, ChapterURL, ChapterURL_origin, no_quotes, ChapterUrlAccess); -- Contribution is also in Chapter if utilities.is_set (Chapter) then Chapter = Chapter .. ChapterFormat ; if 'map' == config.CitationClass and utilities.is_set (TitleType) then Chapter = Chapter .. ' ' .. TitleType; -- map annotation here; not after title end Chapter = Chapter .. sepc .. ' '; elseif utilities.is_set (ChapterFormat) then -- |chapter= not set but |chapter-format= is so ... Chapter = ChapterFormat .. sepc .. ' '; -- ... ChapterFormat has error message, we want to see it end end -- Format main title local plain_title = false; local accept_title; Title, accept_title = utilities.has_accept_as_written (Title, true); -- remove accept-this-as-written markup when it wraps all of <Title> if accept_title and ('' == Title) then -- only support forced empty for now "(())" Title = cfg.messages['notitle']; -- replace by predefined "No title" message -- TODO: utilities.set_message ( 'err_redundant_parameters', ...); -- issue proper error message instead of muting ScriptTitle = ''; -- just mute for now TransTitle = ''; -- just mute for now plain_title = true; -- suppress text decoration for descriptive title utilities.set_message ('maint_untitled'); -- add maint cat end if not accept_title then -- <Title> not wrapped in accept-as-written markup if '...' == Title:sub (-3) then -- if ellipsis is the last three characters of |title= Title = Title:gsub ('(%.%.%.)%.+$', '%1'); -- limit the number of dots to three elseif not mw.ustring.find (Title, '%.%s*%a%.$') and -- end of title is not a 'dot-(optional space-)letter-dot' initialism ... not mw.ustring.find (Title, '%s+%a%.$') then -- ...and not a 'space-letter-dot' initial (''Allium canadense'' L.) Title = mw.ustring.gsub(Title, '%' .. sepc .. '$', ''); -- remove any trailing separator character; sepc and ms.ustring() here for languages that use multibyte separator characters end if utilities.is_set (ArchiveURL) and is_archived_copy (Title) then utilities.set_message ('maint_archived_copy'); -- add maintenance category before we modify the content of Title end if is_generic ('generic_titles', Title) then utilities.set_message ('err_generic_title'); -- set an error message end end if (not plain_title) and (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'document', 'pressrelease', 'podcast', 'newsgroup', 'mailinglist', 'interview', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) or ('map' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)))) then -- special case for cite map when the map is in a periodical treat as an article Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from module provided quote marks Title = utilities.wrap_style ('quoted-title', Title); Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); elseif plain_title or ('report' == config.CitationClass) then -- no styling for cite report and descriptive titles (otherwise same as above) Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); -- for cite report, use this form for trans-title else Title = utilities.wrap_style ('italic-title', Title); Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped TransTitle = utilities.wrap_style ('trans-italic-title', TransTitle); end if utilities.is_set (TransTitle) then if utilities.is_set (Title) then TransTitle = " " .. TransTitle; else utilities.set_message ('err_trans_missing_title', {'title'}); end end if utilities.is_set (Title) then -- TODO: is this the right place to be making Wikisource URLs? if utilities.is_set (TitleLink) and utilities.is_set (URL) then utilities.set_message ('err_wikilink_in_url'); -- set an error message because we can't have both TitleLink = ''; -- unset end if not utilities.is_set (TitleLink) and utilities.is_set (URL) then Title = external_link (URL, Title, URL_origin, UrlAccess) .. TransTitle .. Format; URL = ''; -- unset these because no longer needed Format = ""; elseif utilities.is_set (TitleLink) and not utilities.is_set (URL) then local ws_url; ws_url = wikisource_url_make (TitleLink); -- ignore ws_label return; not used here if ws_url then Title = external_link (ws_url, Title .. '&nbsp;', 'ws link in title-link'); -- space char after Title to move icon away from italic text; TODO: a better way to do this? Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], TitleLink, Title}); Title = Title .. TransTitle; else Title = utilities.make_wikilink (TitleLink, Title) .. TransTitle; end else local ws_url, ws_label, L; -- Title has italic or quote markup by the time we get here which causes is_wikilink() to return 0 (not a wikilink) ws_url, ws_label, L = wikisource_url_make (Title:gsub('^[\'"]*(.-)[\'"]*$', '%1')); -- make ws URL from |title= interwiki link (strip italic or quote markup); link portion L becomes tooltip label if ws_url then Title = Title:gsub ('%b[]', ws_label); -- replace interwiki link with ws_label to retain markup Title = external_link (ws_url, Title .. '&nbsp;', 'ws link in title'); -- space char after Title to move icon away from italic text; TODO: a better way to do this? Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, Title}); Title = Title .. TransTitle; else Title = Title .. TransTitle; end end else Title = TransTitle; end if utilities.is_set (Place) then Place = " " .. wrap_msg ('written', Place, use_lowercase) .. sepc .. " "; end local ConferenceURL_origin = A:ORIGIN('ConferenceURL'); -- get name of parameter that holds ConferenceURL if utilities.is_set (Conference) then if utilities.is_set (ConferenceURL) then Conference = external_link( ConferenceURL, Conference, ConferenceURL_origin, nil ); end Conference = sepc .. " " .. Conference .. ConferenceFormat; elseif utilities.is_set (ConferenceURL) then Conference = sepc .. " " .. external_link( ConferenceURL, nil, ConferenceURL_origin, nil ); end local Position = ''; if not utilities.is_set (Position) then local Minutes = A['Minutes']; local Time = A['Time']; if utilities.is_set (Minutes) then if utilities.is_set (Time) then --TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'minutes') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'time')}); end Position = " " .. Minutes .. " " .. cfg.messages['minutes']; else if utilities.is_set (Time) then local TimeCaption = A['TimeCaption'] if not utilities.is_set (TimeCaption) then TimeCaption = cfg.messages['event']; if sepc ~= '.' then TimeCaption = TimeCaption:lower(); end end Position = " " .. TimeCaption .. " " .. Time; end end else Position = " " .. Position; At = ''; end Page, Pages, Sheet, Sheets = format_pages_sheets (Page, Pages, Sheet, Sheets, config.CitationClass, Periodical_origin, sepc, NoPP, use_lowercase); At = utilities.is_set (At) and (sepc .. " " .. At) or ""; Position = utilities.is_set (Position) and (sepc .. " " .. Position) or ""; if config.CitationClass == 'map' then local Sections = A['Sections']; -- Section (singular) is an alias of Chapter so set earlier local Inset = A['Inset']; if utilities.is_set ( Inset ) then Inset = sepc .. " " .. wrap_msg ('inset', Inset, use_lowercase); end if utilities.is_set ( Sections ) then Section = sepc .. " " .. wrap_msg ('sections', Sections, use_lowercase); elseif utilities.is_set ( Section ) then Section = sepc .. " " .. wrap_msg ('section', Section, use_lowercase); end At = At .. Inset .. Section; end local Others = A['Others']; if utilities.is_set (Others) and 0 == #a and 0 == #e then -- add maint cat when |others= has value and used without |author=, |editor= if config.CitationClass == "AV-media-notes" or config.CitationClass == "audio-visual" then -- special maint for AV/M which has a lot of 'false' positives right now utilities.set_message ('maint_others_avm') else utilities.set_message ('maint_others'); end end Others = utilities.is_set (Others) and (sepc .. " " .. Others) or ""; if utilities.is_set (Translators) then Others = safe_join ({sepc .. ' ', wrap_msg ('translated', Translators, use_lowercase), Others}, sepc); end if utilities.is_set (Interviewers) then Others = safe_join ({sepc .. ' ', wrap_msg ('interview', Interviewers, use_lowercase), Others}, sepc); end local TitleNote = A['TitleNote']; TitleNote = utilities.is_set (TitleNote) and (sepc .. " " .. TitleNote) or ""; if utilities.is_set (Edition) then if Edition:match ('%f[%a][Ee]d%n?%.?$') or Edition:match ('%f[%a][Ee]dition$') then -- Ed, ed, Ed., ed., Edn, edn, Edn., edn. utilities.set_message ('err_extra_text_edition'); -- add error message end Edition = " " .. wrap_msg ('edition', Edition); else Edition = ''; end Series = utilities.is_set (Series) and wrap_msg ('series', {sepc, Series}) or ""; -- not the same as SeriesNum local Agency = A['Agency']; Agency = utilities.is_set (Agency) and wrap_msg ('agency', {sepc, Agency}) or ""; Volume = format_volume_issue (Volume, Issue, ArticleNumber, config.CitationClass, Periodical_origin, sepc, use_lowercase); if utilities.is_set (AccessDate) then local retrv_text = " " .. cfg.messages['retrieved'] AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format if (sepc ~= ".") then retrv_text = retrv_text:lower() end -- if mode is cs2, lower case AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text AccessDate = utilities.substitute (cfg.presentation['accessdate'], {sepc, AccessDate}); -- allow editors to hide accessdates end if utilities.is_set (ID) then ID = sepc .. " " .. ID; end local Docket = A['Docket']; if "thesis" == config.CitationClass and utilities.is_set (Docket) then ID = sepc .. " Docket " .. Docket .. ID; end if "report" == config.CitationClass and utilities.is_set (Docket) then -- for cite report when |docket= is set ID = sepc .. ' ' .. Docket; -- overwrite ID even if |id= is set end if utilities.is_set (URL) then URL = " " .. external_link( URL, nil, URL_origin, UrlAccess ); end local Quote = A['Quote']; local TransQuote = A['TransQuote']; local ScriptQuote = A['ScriptQuote']; if utilities.is_set (Quote) or utilities.is_set (TransQuote) or utilities.is_set (ScriptQuote) then if utilities.is_set (Quote) then if Quote:sub(1, 1) == '"' and Quote:sub(-1, -1) == '"' then -- if first and last characters of quote are quote marks Quote = Quote:sub(2, -2); -- strip them off end end Quote = kern_quotes (Quote); -- kern if needed Quote = utilities.wrap_style ('quoted-text', Quote ); -- wrap in <q>...</q> tags if utilities.is_set (ScriptQuote) then Quote = script_concatenate (Quote, ScriptQuote, 'script-quote'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after quote is wrapped end if utilities.is_set (TransQuote) then if TransQuote:sub(1, 1) == '"' and TransQuote:sub(-1, -1) == '"' then -- if first and last characters of |trans-quote are quote marks TransQuote = TransQuote:sub(2, -2); -- strip them off end Quote = Quote .. " " .. utilities.wrap_style ('trans-quoted-title', TransQuote ); end if utilities.is_set (QuotePage) or utilities.is_set (QuotePages) then -- add page prefix local quote_prefix = ''; if utilities.is_set (QuotePage) then extra_text_in_page_check (QuotePage, 'quote-page'); -- add to maint cat if |quote-page= value begins with what looks like p., pp., etc. if not NoPP then quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePage}), '', '', ''; else quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePage}), '', '', ''; end elseif utilities.is_set (QuotePages) then extra_text_in_page_check (QuotePages, 'quote-pages'); -- add to maint cat if |quote-pages= value begins with what looks like p., pp., etc. if tonumber(QuotePages) ~= nil and not NoPP then -- if only digits, assume single page quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePages}), '', ''; elseif not NoPP then quote_prefix = utilities.substitute (cfg.messages['pp-prefix'], {sepc, QuotePages}), '', ''; else quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePages}), '', ''; end end Quote = quote_prefix .. ": " .. Quote; else Quote = sepc .. " " .. Quote; end PostScript = ""; -- cs1|2 does not supply terminal punctuation when |quote= is set end -- We check length of PostScript here because it will have been nuked by -- the quote parameters. We'd otherwise emit a message even if there wasn't -- a displayed postscript. -- TODO: Should the max size (1) be configurable? -- TODO: Should we check a specific pattern? if utilities.is_set(PostScript) and mw.ustring.len(PostScript) > 1 then utilities.set_message ('maint_postscript') end local Archived; if utilities.is_set (ArchiveURL) then if not utilities.is_set (ArchiveDate) then -- ArchiveURL set but ArchiveDate not set utilities.set_message ('err_archive_missing_date'); -- emit an error message ArchiveURL = ''; -- empty string for concatenation ArchiveDate = ''; -- empty string for concatenation end else if utilities.is_set (ArchiveDate) then -- ArchiveURL not set but ArchiveDate is set utilities.set_message ('err_archive_date_missing_url'); -- emit an error message ArchiveURL = ''; -- empty string for concatenation ArchiveDate = ''; -- empty string for concatenation end end if utilities.is_set (ArchiveURL) then local arch_text; -- if not utilities.is_set (ArchiveDate) then -- utilities.set_message ('err_archive_missing_date'); -- ArchiveDate = ''; -- empty string for concatenation -- end if "live" == UrlStatus then arch_text = cfg.messages['archived']; if sepc ~= "." then arch_text = arch_text:lower() end if utilities.is_set (ArchiveDate) then Archived = sepc .. ' ' .. utilities.substitute ( cfg.messages['archived-live'], {external_link( ArchiveURL, arch_text, A:ORIGIN('ArchiveURL'), nil) .. ArchiveFormat, ArchiveDate } ); else Archived = ''; end if not utilities.is_set (OriginalURL) then utilities.set_message ('err_archive_missing_url'); Archived = ''; -- empty string for concatenation end elseif utilities.is_set (OriginalURL) then -- UrlStatus is empty, 'dead', 'unfit', 'usurped', 'bot: unknown' if utilities.in_array (UrlStatus, {'unfit', 'usurped', 'bot: unknown'}) then arch_text = cfg.messages['archived-unfit']; if sepc ~= "." then arch_text = arch_text:lower() end Archived = sepc .. ' ' .. arch_text .. ArchiveDate; -- format already styled if 'bot: unknown' == UrlStatus then utilities.set_message ('maint_bot_unknown'); -- and add a category if not already added else utilities.set_message ('maint_unfit'); -- and add a category if not already added end else -- UrlStatus is empty, 'dead' arch_text = cfg.messages['archived-dead']; if sepc ~= "." then arch_text = arch_text:lower() end if utilities.is_set (ArchiveDate) then Archived = sepc .. " " .. utilities.substitute ( arch_text, { external_link( OriginalURL, cfg.messages['original'], OriginalURL_origin, OriginalAccess ) .. OriginalFormat, ArchiveDate } ); -- format already styled else Archived = ''; -- unset for concatenation end end else -- OriginalUrl not set utilities.set_message ('err_archive_missing_url'); Archived = ''; -- empty string for concatenation end elseif utilities.is_set (ArchiveFormat) then Archived = ArchiveFormat; -- if set and ArchiveURL not set ArchiveFormat has error message else Archived = ''; end -- local Lay = ''; -- local LaySource = A['LaySource']; -- local LayURL = A['LayURL']; -- local LayFormat = A['LayFormat']; -- LayFormat = style_format (LayFormat, LayURL, 'lay-format', 'lay-url'); -- if utilities.is_set (LayURL) then -- if utilities.is_set (LayDate) then LayDate = " (" .. LayDate .. ")" end -- if utilities.is_set (LaySource) then -- LaySource = " &ndash; ''" .. utilities.safe_for_italics (LaySource) .. "''"; -- else -- LaySource = ""; -- end -- if sepc == '.' then -- Lay = sepc .. " " .. external_link( LayURL, cfg.messages['lay summary'], A:ORIGIN('LayURL'), nil ) .. LayFormat .. LaySource .. LayDate -- else -- Lay = sepc .. " " .. external_link( LayURL, cfg.messages['lay summary']:lower(), A:ORIGIN('LayURL'), nil ) .. LayFormat .. LaySource .. LayDate -- end -- elseif utilities.is_set (LayFormat) then -- Test if |lay-format= is given without giving a |lay-url= -- Lay = sepc .. LayFormat; -- if set and LayURL not set, then LayFormat has error message -- end local TranscriptURL = A['TranscriptURL'] local TranscriptFormat = A['TranscriptFormat']; TranscriptFormat = style_format (TranscriptFormat, TranscriptURL, 'transcript-format', 'transcripturl'); local Transcript = A['Transcript']; local TranscriptURL_origin = A:ORIGIN('TranscriptURL'); -- get name of parameter that holds TranscriptURL if utilities.is_set (Transcript) then if utilities.is_set (TranscriptURL) then Transcript = external_link( TranscriptURL, Transcript, TranscriptURL_origin, nil ); end Transcript = sepc .. ' ' .. Transcript .. TranscriptFormat; elseif utilities.is_set (TranscriptURL) then Transcript = external_link( TranscriptURL, nil, TranscriptURL_origin, nil ); end local Publisher; if utilities.is_set (PublicationDate) then PublicationDate = wrap_msg ('published', PublicationDate); end if utilities.is_set (PublisherName) then if utilities.is_set (PublicationPlace) then Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate; else Publisher = sepc .. " " .. PublisherName .. PublicationDate; end elseif utilities.is_set (PublicationPlace) then Publisher= sepc .. " " .. PublicationPlace .. PublicationDate; else Publisher = PublicationDate; end -- Several of the above rely upon detecting this as nil, so do it last. if (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical)) then if utilities.is_set (Title) or utilities.is_set (TitleNote) then Periodical = sepc .. " " .. format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin); else Periodical = format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin); end end local Language = A['Language']; if utilities.is_set (Language) then Language = language_parameter (Language); -- format, categories, name from ISO639-1, etc. else Language=''; -- language not specified so make sure this is an empty string; --[[ TODO: need to extract the wrap_msg from language_parameter so that we can solve parentheses bunching problem with Format/Language/TitleType ]] end --[[ Handle the oddity that is cite speech. This code overrides whatever may be the value assigned to TitleNote (through |department=) and forces it to be " (Speech)" so that the annotation directly follows the |title= parameter value in the citation rather than the |event= parameter value (if provided). ]] if "speech" == config.CitationClass then -- cite speech only TitleNote = TitleType; -- move TitleType to TitleNote so that it renders ahead of |event= TitleType = ''; -- and unset if utilities.is_set (Periodical) then -- if Periodical, perhaps because of an included |website= or |journal= parameter if utilities.is_set (Conference) then -- and if |event= is set Conference = Conference .. sepc .. " "; -- then add appropriate punctuation to the end of the Conference variable before rendering end end end -- Piece all bits together at last. Here, all should be non-nil. -- We build things this way because it is more efficient in LUA -- not to keep reassigning to the same string variable over and over. local tcommon; local tcommon2; -- used for book cite when |contributor= is set if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then if not (utilities.is_set (Authors) or utilities.is_set (Editors)) then Others = Others:gsub ('^' .. sepc .. ' ', ''); -- when no authors and no editors, strip leading sepc and space end if utilities.is_set (Others) then Others = safe_join ({Others, sepc .. " "}, sepc) end -- add terminal punctuation & space; check for dup sepc; TODO why do we need to do this here? tcommon = safe_join( {Others, Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Edition, Publisher, Agency, Volume}, sepc ); elseif utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (Periodical) then -- special cases for book cites if utilities.is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc. tcommon = safe_join( {Title, TitleNote}, sepc ); -- author and other stuff will come after this and before tcommon2 tcommon2 = safe_join( {Conference, Periodical, Format, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc ); else tcommon = safe_join( {Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc ); end elseif 'map' == config.CitationClass then -- special cases for cite map if utilities.is_set (Chapter) then -- map in a book; TitleType is part of Chapter tcommon = safe_join( {Title, Format, Edition, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc ); elseif utilities.is_set (Periodical) then -- map in a periodical tcommon = safe_join( {Title, TitleType, Format, Periodical, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc ); else -- a sheet or stand-alone map tcommon = safe_join( {Title, TitleType, Format, Edition, Scale, Series, Language, Cartography, Others, Publisher}, sepc ); end elseif 'episode' == config.CitationClass then -- special case for cite episode tcommon = safe_join( {Title, TitleNote, TitleType, Series, Language, Edition, Publisher}, sepc ); else -- all other CS1 templates tcommon = safe_join( {Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc ); end if #ID_list > 0 then ID_list = safe_join( { sepc .. " ", table.concat( ID_list, sepc .. " " ), ID }, sepc ); else ID_list = ID; end local Via = A['Via']; Via = utilities.is_set (Via) and wrap_msg ('via', Via) or ''; local idcommon; if 'audio-visual' == config.CitationClass or 'episode' == config.CitationClass then -- special case for cite AV media & cite episode position transcript -- idcommon = safe_join( { ID_list, URL, Archived, Transcript, AccessDate, Via, Lay, Quote }, sepc ); idcommon = safe_join( { ID_list, URL, Archived, Transcript, AccessDate, Via, Quote }, sepc ); else -- idcommon = safe_join( { ID_list, URL, Archived, AccessDate, Via, Lay, Quote }, sepc ); idcommon = safe_join( { ID_list, URL, Archived, AccessDate, Via, Quote }, sepc ); end local text; local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At; local OrigDate = A['OrigDate']; OrigDate = utilities.is_set (OrigDate) and wrap_msg ('origdate', OrigDate) or ''; if utilities.is_set (Date) then if utilities.is_set (Authors) or utilities.is_set (Editors) then -- date follows authors or editors when authors not set Date = " (" .. Date .. ")" .. OrigDate .. sepc .. " "; -- in parentheses else -- neither of authors and editors set if (string.sub(tcommon, -1, -1) == sepc) then -- if the last character of tcommon is sepc Date = " " .. Date .. OrigDate; -- Date does not begin with sepc else Date = sepc .. " " .. Date .. OrigDate; -- Date begins with sepc end end end if utilities.is_set (Authors) then if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Authors termination Authors = terminate_name_list (Authors, sepc); -- when no date, terminate with 0 or 1 sepc and a space end if utilities.is_set (Editors) then local in_text = ''; local post_text = ''; if utilities.is_set (Chapter) and 0 == #c then in_text = cfg.messages['in'] .. ' '; if (sepc ~= '.') then in_text = in_text:lower(); -- lowercase for cs2 end end if EditorCount <= 1 then post_text = ' (' .. cfg.messages['editor'] .. ')'; -- be consistent with no-author, no-date case else post_text = ' (' .. cfg.messages['editors'] .. ')'; end Editors = terminate_name_list (in_text .. Editors .. post_text, sepc); -- terminate with 0 or 1 sepc and a space end if utilities.is_set (Contributors) then -- book cite and we're citing the intro, preface, etc. local by_text = sepc .. ' ' .. cfg.messages['by'] .. ' '; if (sepc ~= '.') then by_text = by_text:lower() end -- lowercase for cs2 Authors = by_text .. Authors; -- author follows title so tweak it here if utilities.is_set (Editors) and utilities.is_set (Date) then -- when Editors make sure that Authors gets terminated Authors = terminate_name_list (Authors, sepc); -- terminate with 0 or 1 sepc and a space end if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Contributors termination Contributors = terminate_name_list (Contributors, sepc); -- terminate with 0 or 1 sepc and a space end text = safe_join( {Contributors, Date, Chapter, tcommon, Authors, Place, Editors, tcommon2, pgtext, idcommon }, sepc ); else text = safe_join( {Authors, Date, Chapter, Place, Editors, tcommon, pgtext, idcommon }, sepc ); end elseif utilities.is_set (Editors) then if utilities.is_set (Date) then if EditorCount <= 1 then Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editor']; else Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editors']; end else if EditorCount <= 1 then Editors = Editors .. " (" .. cfg.messages['editor'] .. ")" .. sepc .. " " else Editors = Editors .. " (" .. cfg.messages['editors'] .. ")" .. sepc .. " " end end text = safe_join( {Editors, Date, Chapter, Place, tcommon, pgtext, idcommon}, sepc ); else if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then text = safe_join( {Chapter, Place, tcommon, pgtext, Date, idcommon}, sepc ); else text = safe_join( {Chapter, Place, tcommon, Date, pgtext, idcommon}, sepc ); end end if utilities.is_set (PostScript) and PostScript ~= sepc then text = safe_join( {text, sepc}, sepc ); -- Deals with italics, spaces, etc. text = text:sub(1, -sepc:len() - 1); end text = safe_join( {text, PostScript}, sepc ); -- Now enclose the whole thing in a <cite> element local options_t = {}; options_t.class = cite_class_attribute_make (config.CitationClass, Mode); local Ref = is_valid_parameter_value (A['Ref'], A:ORIGIN('Ref'), cfg.keywords_lists['ref'], nil, true); -- nil when |ref=harv; A['Ref'] else if 'none' ~= cfg.keywords_xlate[(Ref and Ref:lower()) or ''] then local namelist_t = {}; -- holds selected contributor, author, editor name list local year = first_set ({Year, anchor_year}, 2); -- Year first for legacy citations and for YMD dates that require disambiguation if #c > 0 then -- if there is a contributor list namelist_t = c; -- select it elseif #a > 0 then -- or an author list namelist_t = a; elseif #e > 0 then -- or an editor list namelist_t = e; end local citeref_id; if #namelist_t > 0 then -- if there are names in namelist_t citeref_id = make_citeref_id (namelist_t, year); -- go make the CITEREF anchor if mw.uri.anchorEncode (citeref_id) == ((Ref and mw.uri.anchorEncode (Ref)) or '') then -- Ref may already be encoded (by {{sfnref}}) so citeref_id must be encoded before comparison utilities.set_message ('maint_ref_duplicates_default'); end else citeref_id = ''; -- unset end options_t.id = Ref or citeref_id; end if string.len (text:gsub('%b<>', '')) <= 2 then -- remove html and html-like tags; then get length of what remains; z.error_cats_t = {}; -- blank the categories list z.error_msgs_t = {}; -- blank the error messages list OCinSoutput = nil; -- blank the metadata string text = ''; -- blank the the citation utilities.set_message ('err_empty_citation'); -- set empty citation message and category end local render_t = {}; -- here we collect the final bits for concatenation into the rendered citation if utilities.is_set (options_t.id) then -- here we wrap the rendered citation in <cite ...>...</cite> tags table.insert (render_t, utilities.substitute (cfg.presentation['cite-id'], {mw.uri.anchorEncode(options_t.id), mw.text.nowiki(options_t.class), text})); -- when |ref= is set or when there is a namelist else table.insert (render_t, utilities.substitute (cfg.presentation['cite'], {mw.text.nowiki(options_t.class), text})); -- when |ref=none or when namelist_t empty and |ref= is missing or is empty end if OCinSoutput then -- blanked when citation is 'empty' so don't bother to add boilerplate metadata span table.insert (render_t, utilities.substitute (cfg.presentation['ocins'], OCinSoutput)); -- format and append metadata to the citation end local template_name = ('citation' == config.CitationClass) and 'citation' or 'cite ' .. (cfg.citation_class_map_t[config.CitationClass] or config.CitationClass); local template_link = '[[Template:' .. template_name .. '|' .. template_name .. ']]'; local msg_prefix = '<code class="cs1-code">{{' .. template_link .. '}}</code>: '; if 0 ~= #z.error_msgs_t then mw.addWarning (utilities.substitute (cfg.messages.warning_msg_e, template_link)); table.insert (render_t, ' '); -- insert a space between citation and its error messages table.sort (z.error_msgs_t); -- sort the error messages list; sorting includes wrapping <span> and <code> tags; hidden-error sorts ahead of visible-error local hidden = true; -- presume that the only error messages emited by this template are hidden for _, v in ipairs (z.error_msgs_t) do -- spin through the list of error messages if v:find ('cs1-visible-error', 1, true) then -- look for the visible error class name hidden = false; -- found one; so don't hide the error message prefix break; -- and done because no need to look further end end z.error_msgs_t[1] = table.concat ({utilities.error_comment (msg_prefix, hidden), z.error_msgs_t[1]}); -- add error message prefix to first error message to prevent extraneous punctuation table.insert (render_t, table.concat (z.error_msgs_t, '; ')); -- make a big string of error messages and add it to the rendering end if 0 ~= #z.maint_cats_t then mw.addWarning (utilities.substitute (cfg.messages.warning_msg_m, template_link)); table.sort (z.maint_cats_t); -- sort the maintenance messages list local maint_msgs_t = {}; -- here we collect all of the maint messages if 0 == #z.error_msgs_t then -- if no error messages table.insert (maint_msgs_t, msg_prefix); -- insert message prefix in maint message livery end for _, v in ipairs( z.maint_cats_t ) do -- append maintenance categories table.insert (maint_msgs_t, -- assemble new maint message and add it to the maint_msgs_t table table.concat ({v, ' (', utilities.substitute (cfg.messages[':cat wikilink'], v), ')'}) ); end table.insert (render_t, utilities.substitute (cfg.presentation['hidden-maint'], table.concat (maint_msgs_t, ' '))); -- wrap the group of maint messages with proper presentation and save end if not no_tracking_cats then for _, v in ipairs (z.error_cats_t) do -- append error categories table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); end for _, v in ipairs (z.maint_cats_t) do -- append maintenance categories table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); end for _, v in ipairs (z.prop_cats_t) do -- append properties categories table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); end end return table.concat (render_t); -- make a big string and done end --[[--------------------------< V A L I D A T E >-------------------------------------------------------------- Looks for a parameter's name in one of several whitelists. Parameters in the whitelist can have three values: true - active, supported parameters false - deprecated, supported parameters nil - unsupported parameters ]] local function validate (name, cite_class, empty) local name = tostring (name); local enum_name; -- parameter name with enumerator (if any) replaced with '#' local state; local function state_test (state, name) -- local function to do testing of state values if true == state then return true; end -- valid actively supported parameter if false == state then if empty then return nil; end -- empty deprecated parameters are treated as unknowns deprecated_parameter (name); -- parameter is deprecated but still supported return true; end if 'tracked' == state then local base_name = name:gsub ('%d', ''); -- strip enumerators from parameter names that have them to get the base name utilities.add_prop_cat ('tracked-param', {base_name}, base_name); -- add a properties category; <base_name> modifies <key> return true; end return nil; end if name:find ('#') then -- # is a cs1|2 reserved character so parameters with # not permitted return nil; end -- replace wnumerator digit(s) with # (|last25= becomes |last#=) (mw.ustring because non-Western 'local' digits) enum_name = mw.ustring.gsub (name, '%d+$', '#'); -- where enumerator is last charaters in parameter name (these to protect |s2cid=) enum_name = mw.ustring.gsub (enum_name, '%d+([%-l])', '#%1'); -- where enumerator is in the middle of the parameter name; |author#link= is the oddity if 'document' == cite_class then -- special case for {{cite document}} state = whitelist.document_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters if true == state_test (state, name) then return true; end return false; end if utilities.in_array (cite_class, whitelist.preprint_template_list_t) then -- limited parameter sets allowed for these templates state = whitelist.limited_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters if true == state_test (state, name) then return true; end state = whitelist.preprint_arguments_t[cite_class][name]; -- look in the parameter-list for the template identified by cite_class if true == state_test (state, name) then return true; end return false; -- not supported because not found or name is set to nil end -- end limited parameter-set templates if utilities.in_array (cite_class, whitelist.unique_param_template_list_t) then -- template-specific parameters for templates that accept parameters from the basic argument list state = whitelist.unique_arguments_t[cite_class][name]; -- look in the template-specific parameter-lists for the template identified by cite_class if true == state_test (state, name) then return true; end end -- if here, fall into general validation state = whitelist.common_parameters_t[enum_name]; -- all other templates; all normal parameters allowed; this list holds enumerated and nonenumerated parameters if true == state_test (state, name) then return true; end return false; -- not supported because not found or name is set to nil end --[=[-------------------------< I N T E R _ W I K I _ C H E C K >---------------------------------------------- check <value> for inter-language interwiki-link markup. <prefix> must be a MediaWiki-recognized language code. when these values have the form (without leading colon): [[<prefix>:link|label]] return label as plain-text [[<prefix>:link]] return <prefix>:link as plain-text return value as is else ]=] local function inter_wiki_check (parameter, value) local prefix = value:match ('%[%[(%a+):'); -- get an interwiki prefix if one exists local _; if prefix and cfg.inter_wiki_map[prefix:lower()] then -- if prefix is in the map, needs preceding colon so utilities.set_message ('err_bad_paramlink', parameter); -- emit an error message _, value, _ = utilities.is_wikilink (value); -- extract label portion from wikilink end return value; end --[[--------------------------< M I S S I N G _ P I P E _ C H E C K >------------------------------------------ Look at the contents of a parameter. If the content has a string of characters and digits followed by an equal sign, compare the alphanumeric string to the list of cs1|2 parameters. If found, then the string is possibly a parameter that is missing its pipe. There are two tests made: {{cite ... |title=Title access-date=2016-03-17}} -- the first parameter has a value and whitespace separates that value from the missing pipe parameter name {{cite ... |title=access-date=2016-03-17}} -- the first parameter has no value (whitespace after the first = is trimmed by MediaWiki) cs1|2 shares some parameter names with XML/HTML attributes: class=, title=, etc. To prevent false positives XML/HTML tags are removed before the search. If a missing pipe is detected, this function adds the missing pipe maintenance category. ]] local function missing_pipe_check (parameter, value) local capture; value = value:gsub ('%b<>', ''); -- remove XML/HTML tags because attributes: class=, title=, etc. capture = value:match ('%s+(%a[%w%-]+)%s*=') or value:match ('^(%a[%w%-]+)%s*='); -- find and categorize parameters with possible missing pipes if capture and validate (capture) then -- if the capture is a valid parameter name utilities.set_message ('err_missing_pipe', parameter); end end --[[--------------------------< H A S _ E X T R A N E O U S _ P U N C T >-------------------------------------- look for extraneous terminal punctuation in most parameter values; parameters listed in skip table are not checked ]] local function has_extraneous_punc (param, value) if 'number' == type (param) then return; end param = param:gsub ('%d+', '#'); -- enumerated name-list mask params allow terminal punct; normalize if cfg.punct_skip[param] then return; -- parameter name found in the skip table so done end if value:match ('[,;:]$') then utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat end if value:match ('^=') then -- sometimes an extraneous '=' character appears ... utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat end end --[[--------------------------< H A S _ E X T R A N E O U S _ U R L >------------------------------------------ look for extraneous url parameter values; parameters listed in skip table are not checked ]] local function has_extraneous_url (url_param_t) local url_error_t = {}; check_for_url (url_param_t, url_error_t); -- extraneous url check if 0 ~= #url_error_t then -- non-zero when there are errors table.sort (url_error_t); utilities.set_message ('err_param_has_ext_link', {utilities.make_sep_list (#url_error_t, url_error_t)}); -- add this error message end end --[[--------------------------< C I T A T I O N >-------------------------------------------------------------- This is used by templates such as {{cite book}} to create the actual citation text. ]] local function citation(frame) Frame = frame; -- save a copy in case we need to display an error message in preview mode local config = {}; -- table to store parameters from the module {{#invoke:}} for k, v in pairs( frame.args ) do -- get parameters from the {{#invoke}} frame config[k] = v; -- args[k] = v; -- crude debug support that allows us to render a citation from module {{#invoke:}}; skips parameter validation; TODO: keep? end -- i18n: set the name that your wiki uses to identify sandbox subpages from sandbox template invoke (or can be set here) local sandbox = ((config.SandboxPath and '' ~= config.SandboxPath) and config.SandboxPath) or '/sandbox'; -- sandbox path from {{#invoke:Citation/CS1/sandbox|citation|SandboxPath=/...}} is_sandbox = nil ~= string.find (frame:getTitle(), sandbox, 1, true); -- is this invoke the sandbox module? sandbox = is_sandbox and sandbox or ''; -- use i18n sandbox to load sandbox modules when this module is the sandox; live modules else local pframe = frame:getParent() local styles; cfg = mw.loadData ('Module:Citation/CS1/Configuration' .. sandbox); -- load sandbox versions of support modules when {{#invoke:Citation/CS1/sandbox|...}}; live modules else whitelist = mw.loadData ('Module:Citation/CS1/Whitelist' .. sandbox); utilities = require ('Module:Citation/CS1/Utilities' .. sandbox); validation = require ('Module:Citation/CS1/Date_validation' .. sandbox); identifiers = require ('Module:Citation/CS1/Identifiers' .. sandbox); metadata = require ('Module:Citation/CS1/COinS' .. sandbox); styles = 'Module:Citation/CS1' .. sandbox .. '/styles.css'; utilities.set_selected_modules (cfg); -- so that functions in Utilities can see the selected cfg tables identifiers.set_selected_modules (cfg, utilities); -- so that functions in Identifiers can see the selected cfg tables and selected Utilities module validation.set_selected_modules (cfg, utilities); -- so that functions in Date validataion can see selected cfg tables and the selected Utilities module metadata.set_selected_modules (cfg, utilities); -- so that functions in COinS can see the selected cfg tables and selected Utilities module z = utilities.z; -- table of error and category tables in Module:Citation/CS1/Utilities is_preview_mode = not utilities.is_set (frame:preprocess ('{{REVISIONID}}')); local args = {}; -- table where we store all of the template's arguments local suggestions = {}; -- table where we store suggestions if we need to loadData them local error_text; -- used as a flag local capture; -- the single supported capture when matching unknown parameters using patterns local empty_unknowns = {}; -- sequence table to hold empty unknown params for error message listing for k, v in pairs( pframe.args ) do -- get parameters from the parent (template) frame v = mw.ustring.gsub (v, '^%s*(.-)%s*$', '%1'); -- trim leading/trailing whitespace; when v is only whitespace, becomes empty string if v ~= '' then if ('string' == type (k)) then k = mw.ustring.gsub (k, '%d', cfg.date_names.local_digits); -- for enumerated parameters, translate 'local' digits to Western 0-9 end if not validate( k, config.CitationClass ) then if type (k) ~= 'string' then -- exclude empty numbered parameters if v:match("%S+") ~= nil then error_text = utilities.set_message ('err_text_ignored', {v}); end elseif validate (k:lower(), config.CitationClass) then error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, k:lower()}); -- suggest the lowercase version of the parameter else if nil == suggestions.suggestions then -- if this table is nil then we need to load it suggestions = mw.loadData ('Module:Citation/CS1/Suggestions' .. sandbox); --load sandbox version of suggestion module when {{#invoke:Citation/CS1/sandbox|...}}; live module else end for pattern, param in pairs (suggestions.patterns) do -- loop through the patterns to see if we can suggest a proper parameter capture = k:match (pattern); -- the whole match if no capture in pattern else the capture if a match if capture then -- if the pattern matches param = utilities.substitute (param, capture); -- add the capture to the suggested parameter (typically the enumerator) if validate (param, config.CitationClass) then -- validate the suggestion to make sure that the suggestion is supported by this template (necessary for limited parameter lists) error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, param}); -- set the suggestion error message else error_text = utilities.set_message ('err_parameter_ignored', {k}); -- suggested param not supported by this template v = ''; -- unset end end end if not utilities.is_set (error_text) then -- couldn't match with a pattern, is there an explicit suggestion? if (suggestions.suggestions[ k:lower() ] ~= nil) and validate (suggestions.suggestions[ k:lower() ], config.CitationClass) then utilities.set_message ('err_parameter_ignored_suggest', {k, suggestions.suggestions[ k:lower() ]}); else utilities.set_message ('err_parameter_ignored', {k}); v = ''; -- unset value assigned to unrecognized parameters (this for the limited parameter lists) end end end end args[k] = v; -- save this parameter and its value elseif not utilities.is_set (v) then -- for empty parameters if not validate (k, config.CitationClass, true) then -- is this empty parameter a valid parameter k = ('' == k) and '(empty string)' or k; -- when k is empty string (or was space(s) trimmed to empty string), replace with descriptive text table.insert (empty_unknowns, utilities.wrap_style ('parameter', k)); -- format for error message and add to the list end -- crude debug support that allows us to render a citation from module {{#invoke:}} TODO: keep? -- elseif args[k] ~= nil or (k == 'postscript') then -- when args[k] has a value from {{#invoke}} frame (we don't normally do that) -- args[k] = v; -- overwrite args[k] with empty string from pframe.args[k] (template frame); v is empty string here end -- not sure about the postscript bit; that gets handled in parameter validation; historical artifact? end if 0 ~= #empty_unknowns then -- create empty unknown error message utilities.set_message ('err_param_unknown_empty', { 1 == #empty_unknowns and '' or 's', utilities.make_sep_list (#empty_unknowns, empty_unknowns) }); end local url_param_t = {}; for k, v in pairs( args ) do if 'string' == type (k) then -- don't evaluate positional parameters has_invisible_chars (k, v); -- look for invisible characters end has_extraneous_punc (k, v); -- look for extraneous terminal punctuation in parameter values missing_pipe_check (k, v); -- do we think that there is a parameter that is missing a pipe? args[k] = inter_wiki_check (k, v); -- when language interwiki-linked parameter missing leading colon replace with wiki-link label if 'string' == type (k) and not cfg.url_skip[k] then -- when parameter k is not positional and not in url skip table url_param_t[k] = v; -- make a parameter/value list for extraneous url check end end has_extraneous_url (url_param_t); -- look for url in parameter values where a url does not belong return table.concat ({ frame:extensionTag ('templatestyles', '', {src=styles}), citation0( config, args) }); end --[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------ ]] return {citation = citation}; 03d0c65e9544044eef296e124f940c7cc9319972 120 119 2023-10-05T14:45:26Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Citation/CS1]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain require ('strict'); --[[--------------------------< F O R W A R D D E C L A R A T I O N S >-------------------------------------- each of these counts against the Lua upvalue limit ]] local validation; -- functions in Module:Citation/CS1/Date_validation local utilities; -- functions in Module:Citation/CS1/Utilities local z = {}; -- table of tables in Module:Citation/CS1/Utilities local identifiers; -- functions and tables in Module:Citation/CS1/Identifiers local metadata; -- functions in Module:Citation/CS1/COinS local cfg = {}; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration local whitelist = {}; -- table of tables listing valid template parameter names; defined in Module:Citation/CS1/Whitelist --[[------------------< P A G E S C O P E V A R I A B L E S >--------------- declare variables here that have page-wide scope that are not brought in from other modules; that are created here and used here ]] local added_deprecated_cat; -- Boolean flag so that the category is added only once local added_vanc_errs; -- Boolean flag so we only emit one Vancouver error / category local added_generic_name_errs; -- Boolean flag so we only emit one generic name error / category and stop testing names once an error is encountered local Frame; -- holds the module's frame table local is_preview_mode; -- true when article is in preview mode; false when using 'Preview page with this template' (previewing the module) local is_sandbox; -- true when using sandbox modules to render citation --[[--------------------------< F I R S T _ S E T >------------------------------------------------------------ Locates and returns the first set value in a table of values where the order established in the table, left-to-right (or top-to-bottom), is the order in which the values are evaluated. Returns nil if none are set. This version replaces the original 'for _, val in pairs do' and a similar version that used ipairs. With the pairs version the order of evaluation could not be guaranteed. With the ipairs version, a nil value would terminate the for-loop before it reached the actual end of the list. ]] local function first_set (list, count) local i = 1; while i <= count do -- loop through all items in list if utilities.is_set( list[i] ) then return list[i]; -- return the first set list member end i = i + 1; -- point to next end end --[[--------------------------< A D D _ V A N C _ E R R O R >---------------------------------------------------- Adds a single Vancouver system error message to the template's output regardless of how many error actually exist. To prevent duplication, added_vanc_errs is nil until an error message is emitted. added_vanc_errs is a Boolean declared in page scope variables above ]] local function add_vanc_error (source, position) if added_vanc_errs then return end added_vanc_errs = true; -- note that we've added this category utilities.set_message ('err_vancouver', {source, position}); end --[[--------------------------< I S _ S C H E M E >------------------------------------------------------------ does this thing that purports to be a URI scheme seem to be a valid scheme? The scheme is checked to see if it is in agreement with http://tools.ietf.org/html/std66#section-3.1 which says: Scheme names consist of a sequence of characters beginning with a letter and followed by any combination of letters, digits, plus ("+"), period ("."), or hyphen ("-"). returns true if it does, else false ]] local function is_scheme (scheme) return scheme and scheme:match ('^%a[%a%d%+%.%-]*:'); -- true if scheme is set and matches the pattern end --[=[-------------------------< I S _ D O M A I N _ N A M E >-------------------------------------------------- Does this thing that purports to be a domain name seem to be a valid domain name? Syntax defined here: http://tools.ietf.org/html/rfc1034#section-3.5 BNF defined here: https://tools.ietf.org/html/rfc4234 Single character names are generally reserved; see https://tools.ietf.org/html/draft-ietf-dnsind-iana-dns-01#page-15; see also [[Single-letter second-level domain]] list of TLDs: https://www.iana.org/domains/root/db RFC 952 (modified by RFC 1123) requires the first and last character of a hostname to be a letter or a digit. Between the first and last characters the name may use letters, digits, and the hyphen. Also allowed are IPv4 addresses. IPv6 not supported domain is expected to be stripped of any path so that the last character in the last character of the TLD. tld is two or more alpha characters. Any preceding '//' (from splitting a URL with a scheme) will be stripped here. Perhaps not necessary but retained in case it is necessary for IPv4 dot decimal. There are several tests: the first character of the whole domain name including subdomains must be a letter or a digit internationalized domain name (ASCII characters with .xn-- ASCII Compatible Encoding (ACE) prefix xn-- in the TLD) see https://tools.ietf.org/html/rfc3490 single-letter/digit second-level domains in the .org, .cash, and .today TLDs q, x, and z SL domains in the .com TLD i and q SL domains in the .net TLD single-letter SL domains in the ccTLDs (where the ccTLD is two letters) two-character SL domains in gTLDs (where the gTLD is two or more letters) three-plus-character SL domains in gTLDs (where the gTLD is two or more letters) IPv4 dot-decimal address format; TLD not allowed returns true if domain appears to be a proper name and TLD or IPv4 address, else false ]=] local function is_domain_name (domain) if not domain then return false; -- if not set, abandon end domain = domain:gsub ('^//', ''); -- strip '//' from domain name if present; done here so we only have to do it once if not domain:match ('^[%w]') then -- first character must be letter or digit return false; end if domain:match ('^%a+:') then -- hack to detect things that look like s:Page:Title where Page: is namespace at Wikisource return false; end local patterns = { -- patterns that look like URLs '%f[%w][%w][%w%-]+[%w]%.%a%a+$', -- three or more character hostname.hostname or hostname.tld '%f[%w][%w][%w%-]+[%w]%.xn%-%-[%w]+$', -- internationalized domain name with ACE prefix '%f[%a][qxz]%.com$', -- assigned one character .com hostname (x.com times out 2015-12-10) '%f[%a][iq]%.net$', -- assigned one character .net hostname (q.net registered but not active 2015-12-10) '%f[%w][%w]%.%a%a$', -- one character hostname and ccTLD (2 chars) '%f[%w][%w][%w]%.%a%a+$', -- two character hostname and TLD '^%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?', -- IPv4 address } for _, pattern in ipairs (patterns) do -- loop through the patterns list if domain:match (pattern) then return true; -- if a match then we think that this thing that purports to be a URL is a URL end end for _, d in ipairs (cfg.single_letter_2nd_lvl_domains_t) do -- look for single letter second level domain names for these top level domains if domain:match ('%f[%w][%w]%.' .. d) then return true end end return false; -- no matches, we don't know what this thing is end --[[--------------------------< I S _ U R L >------------------------------------------------------------------ returns true if the scheme and domain parts of a URL appear to be a valid URL; else false. This function is the last step in the validation process. This function is separate because there are cases that are not covered by split_url(), for example is_parameter_ext_wikilink() which is looking for bracketted external wikilinks. ]] local function is_url (scheme, domain) if utilities.is_set (scheme) then -- if scheme is set check it and domain return is_scheme (scheme) and is_domain_name (domain); else return is_domain_name (domain); -- scheme not set when URL is protocol-relative end end --[[--------------------------< S P L I T _ U R L >------------------------------------------------------------ Split a URL into a scheme, authority indicator, and domain. First remove Fully Qualified Domain Name terminator (a dot following TLD) (if any) and any path(/), query(?) or fragment(#). If protocol-relative URL, return nil scheme and domain else return nil for both scheme and domain. When not protocol-relative, get scheme, authority indicator, and domain. If there is an authority indicator (one or more '/' characters immediately following the scheme's colon), make sure that there are only 2. Any URL that does not have news: scheme must have authority indicator (//). TODO: are there other common schemes like news: that don't use authority indicator? Strip off any port and path; ]] local function split_url (url_str) local scheme, authority, domain; url_str = url_str:gsub ('([%a%d])%.?[/%?#].*$', '%1'); -- strip FQDN terminator and path(/), query(?), fragment (#) (the capture prevents false replacement of '//') if url_str:match ('^//%S*') then -- if there is what appears to be a protocol-relative URL domain = url_str:match ('^//(%S*)') elseif url_str:match ('%S-:/*%S+') then -- if there is what appears to be a scheme, optional authority indicator, and domain name scheme, authority, domain = url_str:match ('(%S-:)(/*)(%S+)'); -- extract the scheme, authority indicator, and domain portions if utilities.is_set (authority) then authority = authority:gsub ('//', '', 1); -- replace place 1 pair of '/' with nothing; if utilities.is_set(authority) then -- if anything left (1 or 3+ '/' where authority should be) then return scheme; -- return scheme only making domain nil which will cause an error message end else if not scheme:match ('^news:') then -- except for news:..., MediaWiki won't link URLs that do not have authority indicator; TODO: a better way to do this test? return scheme; -- return scheme only making domain nil which will cause an error message end end domain = domain:gsub ('(%a):%d+', '%1'); -- strip port number if present end return scheme, domain; end --[[--------------------------< L I N K _ P A R A M _ O K >--------------------------------------------------- checks the content of |title-link=, |series-link=, |author-link=, etc. for properly formatted content: no wikilinks, no URLs Link parameters are to hold the title of a Wikipedia article, so none of the WP:TITLESPECIALCHARACTERS are allowed: # < > [ ] | { } _ except the underscore which is used as a space in wiki URLs and # which is used for section links returns false when the value contains any of these characters. When there are no illegal characters, this function returns TRUE if value DOES NOT appear to be a valid URL (the |<param>-link= parameter is ok); else false when value appears to be a valid URL (the |<param>-link= parameter is NOT ok). ]] local function link_param_ok (value) local scheme, domain; if value:find ('[<>%[%]|{}]') then -- if any prohibited characters return false; end scheme, domain = split_url (value); -- get scheme or nil and domain or nil from URL; return not is_url (scheme, domain); -- return true if value DOES NOT appear to be a valid URL end --[[--------------------------< L I N K _ T I T L E _ O K >--------------------------------------------------- Use link_param_ok() to validate |<param>-link= value and its matching |<title>= value. |<title>= may be wiki-linked but not when |<param>-link= has a value. This function emits an error message when that condition exists check <link> for inter-language interwiki-link prefix. prefix must be a MediaWiki-recognized language code and must begin with a colon. ]] local function link_title_ok (link, lorig, title, torig) local orig; if utilities.is_set (link) then -- don't bother if <param>-link doesn't have a value if not link_param_ok (link) then -- check |<param>-link= markup orig = lorig; -- identify the failing link parameter elseif title:find ('%[%[') then -- check |title= for wikilink markup orig = torig; -- identify the failing |title= parameter elseif link:match ('^%a+:') then -- if the link is what looks like an interwiki local prefix = link:match ('^(%a+):'):lower(); -- get the interwiki prefix if cfg.inter_wiki_map[prefix] then -- if prefix is in the map, must have preceding colon orig = lorig; -- flag as error end end end if utilities.is_set (orig) then link = ''; -- unset utilities.set_message ('err_bad_paramlink', orig); -- URL or wikilink in |title= with |title-link=; end return link; -- link if ok, empty string else end --[[--------------------------< C H E C K _ U R L >------------------------------------------------------------ Determines whether a URL string appears to be valid. First we test for space characters. If any are found, return false. Then split the URL into scheme and domain portions, or for protocol-relative (//example.com) URLs, just the domain. Use is_url() to validate the two portions of the URL. If both are valid, or for protocol-relative if domain is valid, return true, else false. Because it is different from a standard URL, and because this module used external_link() to make external links that work for standard and news: links, we validate newsgroup names here. The specification for a newsgroup name is at https://tools.ietf.org/html/rfc5536#section-3.1.4 ]] local function check_url( url_str ) if nil == url_str:match ("^%S+$") then -- if there are any spaces in |url=value it can't be a proper URL return false; end local scheme, domain; scheme, domain = split_url (url_str); -- get scheme or nil and domain or nil from URL; if 'news:' == scheme then -- special case for newsgroups return domain:match('^[%a%d%+%-_]+%.[%a%d%+%-_%.]*[%a%d%+%-_]$'); end return is_url (scheme, domain); -- return true if value appears to be a valid URL end --[=[-------------------------< I S _ P A R A M E T E R _ E X T _ W I K I L I N K >---------------------------- Return true if a parameter value has a string that begins and ends with square brackets [ and ] and the first non-space characters following the opening bracket appear to be a URL. The test will also find external wikilinks that use protocol-relative URLs. Also finds bare URLs. The frontier pattern prevents a match on interwiki-links which are similar to scheme:path URLs. The tests that find bracketed URLs are required because the parameters that call this test (currently |title=, |chapter=, |work=, and |publisher=) may have wikilinks and there are articles or redirects like '//Hus' so, while uncommon, |title=[[//Hus]] is possible as might be [[en://Hus]]. ]=] local function is_parameter_ext_wikilink (value) local scheme, domain; if value:match ('%f[%[]%[%a%S*:%S+.*%]') then -- if ext. wikilink with scheme and domain: [xxxx://yyyyy.zzz] scheme, domain = split_url (value:match ('%f[%[]%[(%a%S*:%S+).*%]')); elseif value:match ('%f[%[]%[//%S+.*%]') then -- if protocol-relative ext. wikilink: [//yyyyy.zzz] scheme, domain = split_url (value:match ('%f[%[]%[(//%S+).*%]')); elseif value:match ('%a%S*:%S+') then -- if bare URL with scheme; may have leading or trailing plain text scheme, domain = split_url (value:match ('(%a%S*:%S+)')); elseif value:match ('//%S+') then -- if protocol-relative bare URL: //yyyyy.zzz; may have leading or trailing plain text scheme, domain = split_url (value:match ('(//%S+)')); -- what is left should be the domain else return false; -- didn't find anything that is obviously a URL end return is_url (scheme, domain); -- return true if value appears to be a valid URL end --[[-------------------------< C H E C K _ F O R _ U R L >----------------------------------------------------- loop through a list of parameters and their values. Look at the value and if it has an external link, emit an error message. ]] local function check_for_url (parameter_list, error_list) for k, v in pairs (parameter_list) do -- for each parameter in the list if is_parameter_ext_wikilink (v) then -- look at the value; if there is a URL add an error message table.insert (error_list, utilities.wrap_style ('parameter', k)); end end end --[[--------------------------< S A F E _ F O R _ U R L >------------------------------------------------------ Escape sequences for content that will be used for URL descriptions ]] local function safe_for_url( str ) if str:match( "%[%[.-%]%]" ) ~= nil then utilities.set_message ('err_wikilink_in_url', {}); end return str:gsub( '[%[%]\n]', { ['['] = '&#91;', [']'] = '&#93;', ['\n'] = ' ' } ); end --[[--------------------------< E X T E R N A L _ L I N K >---------------------------------------------------- Format an external link with error checking ]] local function external_link (URL, label, source, access) local err_msg = ''; local domain; local path; local base_url; if not utilities.is_set (label) then label = URL; if utilities.is_set (source) then utilities.set_message ('err_bare_url_missing_title', {utilities.wrap_style ('parameter', source)}); else error (cfg.messages["bare_url_no_origin"]); -- programmer error; valid parameter name does not have matching meta-parameter end end if not check_url (URL) then utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); end domain, path = URL:match ('^([/%.%-%+:%a%d]+)([/%?#].*)$'); -- split the URL into scheme plus domain and path if path then -- if there is a path portion path = path:gsub ('[%[%]]', {['['] = '%5b', [']'] = '%5d'}); -- replace '[' and ']' with their percent-encoded values URL = table.concat ({domain, path}); -- and reassemble end base_url = table.concat ({ "[", URL, " ", safe_for_url (label), "]" }); -- assemble a wiki-markup URL if utilities.is_set (access) then -- access level (subscription, registration, limited) base_url = utilities.substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[access].class, cfg.presentation[access].title, base_url}); -- add the appropriate icon end return base_url; end --[[--------------------------< D E P R E C A T E D _ P A R A M E T E R >-------------------------------------- Categorize and emit an error message when the citation contains one or more deprecated parameters. The function includes the offending parameter name to the error message. Only one error message is emitted regardless of the number of deprecated parameters in the citation. added_deprecated_cat is a Boolean declared in page scope variables above ]] local function deprecated_parameter(name) if not added_deprecated_cat then added_deprecated_cat = true; -- note that we've added this category utilities.set_message ('err_deprecated_params', {name}); -- add error message end end --[=[-------------------------< K E R N _ Q U O T E S >-------------------------------------------------------- Apply kerning to open the space between the quote mark provided by the module and a leading or trailing quote mark contained in a |title= or |chapter= parameter's value. This function will positive kern either single or double quotes: "'Unkerned title with leading and trailing single quote marks'" " 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example) Double single quotes (italic or bold wiki-markup) are not kerned. Replaces Unicode quote marks in plain text or in the label portion of a [[L|D]] style wikilink with typewriter quote marks regardless of the need for kerning. Unicode quote marks are not replaced in simple [[D]] wikilinks. Call this function for chapter titles, for website titles, etc.; not for book titles. ]=] local function kern_quotes (str) local cap = ''; local wl_type, label, link; wl_type, label, link = utilities.is_wikilink (str); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]] if 1 == wl_type then -- [[D]] simple wikilink with or without quote marks if mw.ustring.match (str, '%[%[[\"“”\'‘’].+[\"“”\'‘’]%]%]') then -- leading and trailing quote marks str = utilities.substitute (cfg.presentation['kern-left'], str); str = utilities.substitute (cfg.presentation['kern-right'], str); elseif mw.ustring.match (str, '%[%[[\"“”\'‘’].+%]%]') then -- leading quote marks str = utilities.substitute (cfg.presentation['kern-left'], str); elseif mw.ustring.match (str, '%[%[.+[\"“”\'‘’]%]%]') then -- trailing quote marks str = utilities.substitute (cfg.presentation['kern-right'], str); end else -- plain text or [[L|D]]; text in label variable label = mw.ustring.gsub (label, '[“”]', '\"'); -- replace “” (U+201C & U+201D) with " (typewriter double quote mark) label = mw.ustring.gsub (label, '[‘’]', '\''); -- replace ‘’ (U+2018 & U+2019) with ' (typewriter single quote mark) cap = mw.ustring.match (label, "^([\"\'][^\'].+)"); -- match leading double or single quote but not doubled single quotes (italic markup) if utilities.is_set (cap) then label = utilities.substitute (cfg.presentation['kern-left'], cap); end cap = mw.ustring.match (label, "^(.+[^\'][\"\'])$") -- match trailing double or single quote but not doubled single quotes (italic markup) if utilities.is_set (cap) then label = utilities.substitute (cfg.presentation['kern-right'], cap); end if 2 == wl_type then str = utilities.make_wikilink (link, label); -- reassemble the wikilink else str = label; end end return str; end --[[--------------------------< F O R M A T _ S C R I P T _ V A L U E >---------------------------------------- |script-title= holds title parameters that are not written in Latin-based scripts: Chinese, Japanese, Arabic, Hebrew, etc. These scripts should not be italicized and may be written right-to-left. The value supplied by |script-title= is concatenated onto Title after Title has been wrapped in italic markup. Regardless of language, all values provided by |script-title= are wrapped in <bdi>...</bdi> tags to isolate RTL languages from the English left to right. |script-title= provides a unique feature. The value in |script-title= may be prefixed with a two-character ISO 639-1 language code and a colon: |script-title=ja:*** *** (where * represents a Japanese character) Spaces between the two-character code and the colon and the colon and the first script character are allowed: |script-title=ja : *** *** |script-title=ja: *** *** |script-title=ja :*** *** Spaces preceding the prefix are allowed: |script-title = ja:*** *** The prefix is checked for validity. If it is a valid ISO 639-1 language code, the lang attribute (lang="ja") is added to the <bdi> tag so that browsers can know the language the tag contains. This may help the browser render the script more correctly. If the prefix is invalid, the lang attribute is not added. At this time there is no error message for this condition. Supports |script-title=, |script-chapter=, |script-<periodical>= ]] local function format_script_value (script_value, script_param) local lang=''; -- initialize to empty string local name; if script_value:match('^%l%l%l?%s*:') then -- if first 3 or 4 non-space characters are script language prefix lang = script_value:match('^(%l%l%l?)%s*:%s*%S.*'); -- get the language prefix or nil if there is no script if not utilities.is_set (lang) then utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing title part']}); -- prefix without 'title'; add error message return ''; -- script_value was just the prefix so return empty string end -- if we get this far we have prefix and script name = cfg.lang_tag_remap[lang] or mw.language.fetchLanguageName( lang, cfg.this_wiki_code ); -- get language name so that we can use it to categorize if utilities.is_set (name) then -- is prefix a proper ISO 639-1 language code? script_value = script_value:gsub ('^%l+%s*:%s*', ''); -- strip prefix from script -- is prefix one of these language codes? if utilities.in_array (lang, cfg.script_lang_codes) then utilities.add_prop_cat ('script', {name, lang}) else utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['unknown language code']}); -- unknown script-language; add error message end lang = ' lang="' .. lang .. '" '; -- convert prefix into a lang attribute else utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['invalid language code']}); -- invalid language code; add error message lang = ''; -- invalid so set lang to empty string end else utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing prefix']}); -- no language code prefix; add error message end script_value = utilities.substitute (cfg.presentation['bdi'], {lang, script_value}); -- isolate in case script is RTL return script_value; end --[[--------------------------< S C R I P T _ C O N C A T E N A T E >------------------------------------------ Initially for |title= and |script-title=, this function concatenates those two parameter values after the script value has been wrapped in <bdi> tags. ]] local function script_concatenate (title, script, script_param) if utilities.is_set (script) then script = format_script_value (script, script_param); -- <bdi> tags, lang attribute, categorization, etc.; returns empty string on error if utilities.is_set (script) then title = title .. ' ' .. script; -- concatenate title and script title end end return title; end --[[--------------------------< W R A P _ M S G >-------------------------------------------------------------- Applies additional message text to various parameter values. Supplied string is wrapped using a message_list configuration taking one argument. Supports lower case text for {{citation}} templates. Additional text taken from citation_config.messages - the reason this function is similar to but separate from wrap_style(). ]] local function wrap_msg (key, str, lower) if not utilities.is_set ( str ) then return ""; end if true == lower then local msg; msg = cfg.messages[key]:lower(); -- set the message to lower case before return utilities.substitute ( msg, str ); -- including template text else return utilities.substitute ( cfg.messages[key], str ); end end --[[----------------< W I K I S O U R C E _ U R L _ M A K E >------------------- Makes a Wikisource URL from Wikisource interwiki-link. Returns the URL and appropriate label; nil else. str is the value assigned to |chapter= (or aliases) or |title= or |title-link= ]] local function wikisource_url_make (str) local wl_type, D, L; local ws_url, ws_label; local wikisource_prefix = table.concat ({'https://', cfg.this_wiki_code, '.wikisource.org/wiki/'}); wl_type, D, L = utilities.is_wikilink (str); -- wl_type is 0 (not a wikilink), 1 (simple wikilink), 2 (complex wikilink) if 0 == wl_type then -- not a wikilink; might be from |title-link= str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace if utilities.is_set (str) then ws_url = table.concat ({ -- build a Wikisource URL wikisource_prefix, -- prefix str, -- article title }); ws_label = str; -- label for the URL end elseif 1 == wl_type then -- simple wikilink: [[Wikisource:ws article]] str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace if utilities.is_set (str) then ws_url = table.concat ({ -- build a Wikisource URL wikisource_prefix, -- prefix str, -- article title }); ws_label = str; -- label for the URL end elseif 2 == wl_type then -- non-so-simple wikilink: [[Wikisource:ws article|displayed text]] ([[L|D]]) str = L:match ('^[Ww]ikisource:(.+)') or L:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace if utilities.is_set (str) then ws_label = D; -- get ws article name from display portion of interwiki link ws_url = table.concat ({ -- build a Wikisource URL wikisource_prefix, -- prefix str, -- article title without namespace from link portion of wikilink }); end end if ws_url then ws_url = mw.uri.encode (ws_url, 'WIKI'); -- make a usable URL ws_url = ws_url:gsub ('%%23', '#'); -- undo percent-encoding of fragment marker end return ws_url, ws_label, L or D; -- return proper URL or nil and a label or nil end --[[----------------< F O R M A T _ P E R I O D I C A L >----------------------- Format the three periodical parameters: |script-<periodical>=, |<periodical>=, and |trans-<periodical>= into a single Periodical meta-parameter. ]] local function format_periodical (script_periodical, script_periodical_source, periodical, trans_periodical) if not utilities.is_set (periodical) then periodical = ''; -- to be safe for concatenation else periodical = utilities.wrap_style ('italic-title', periodical); -- style end periodical = script_concatenate (periodical, script_periodical, script_periodical_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped if utilities.is_set (trans_periodical) then trans_periodical = utilities.wrap_style ('trans-italic-title', trans_periodical); if utilities.is_set (periodical) then periodical = periodical .. ' ' .. trans_periodical; else -- here when trans-periodical without periodical or script-periodical periodical = trans_periodical; utilities.set_message ('err_trans_missing_title', {'periodical'}); end end return periodical; end --[[------------------< F O R M A T _ C H A P T E R _ T I T L E >--------------- Format the four chapter parameters: |script-chapter=, |chapter=, |trans-chapter=, and |chapter-url= into a single chapter meta- parameter (chapter_url_source used for error messages). ]] local function format_chapter_title (script_chapter, script_chapter_source, chapter, chapter_source, trans_chapter, trans_chapter_source, chapter_url, chapter_url_source, no_quotes, access) local ws_url, ws_label, L = wikisource_url_make (chapter); -- make a wikisource URL and label from a wikisource interwiki link if ws_url then ws_label = ws_label:gsub ('_', ' '); -- replace underscore separators with space characters chapter = ws_label; end if not utilities.is_set (chapter) then chapter = ''; -- to be safe for concatenation else if false == no_quotes then chapter = kern_quotes (chapter); -- if necessary, separate chapter title's leading and trailing quote marks from module provided quote marks chapter = utilities.wrap_style ('quoted-title', chapter); end end chapter = script_concatenate (chapter, script_chapter, script_chapter_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped if utilities.is_set (chapter_url) then chapter = external_link (chapter_url, chapter, chapter_url_source, access); -- adds bare_url_missing_title error if appropriate elseif ws_url then chapter = external_link (ws_url, chapter .. '&nbsp;', 'ws link in chapter'); -- adds bare_url_missing_title error if appropriate; space char to move icon away from chap text; TODO: better way to do this? chapter = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, chapter}); end if utilities.is_set (trans_chapter) then trans_chapter = utilities.wrap_style ('trans-quoted-title', trans_chapter); if utilities.is_set (chapter) then chapter = chapter .. ' ' .. trans_chapter; else -- here when trans_chapter without chapter or script-chapter chapter = trans_chapter; chapter_source = trans_chapter_source:match ('trans%-?(.+)'); -- when no chapter, get matching name from trans-<param> utilities.set_message ('err_trans_missing_title', {chapter_source}); end end return chapter; end --[[----------------< H A S _ I N V I S I B L E _ C H A R S >------------------- This function searches a parameter's value for non-printable or invisible characters. The search stops at the first match. This function will detect the visible replacement character when it is part of the Wikisource. Detects but ignores nowiki and math stripmarkers. Also detects other named stripmarkers (gallery, math, pre, ref) and identifies them with a slightly different error message. See also coins_cleanup(). Output of this function is an error message that identifies the character or the Unicode group, or the stripmarker that was detected along with its position (or, for multi-byte characters, the position of its first byte) in the parameter value. ]] local function has_invisible_chars (param, v) local position = ''; -- position of invisible char or starting position of stripmarker local capture; -- used by stripmarker detection to hold name of the stripmarker local stripmarker; -- boolean set true when a stripmarker is found capture = string.match (v, '[%w%p ]*'); -- test for values that are simple ASCII text and bypass other tests if true if capture == v then -- if same there are no Unicode characters return; end for _, invisible_char in ipairs (cfg.invisible_chars) do local char_name = invisible_char[1]; -- the character or group name local pattern = invisible_char[2]; -- the pattern used to find it position, _, capture = mw.ustring.find (v, pattern); -- see if the parameter value contains characters that match the pattern if position and (cfg.invisible_defs.zwj == capture) then -- if we found a zero-width joiner character if mw.ustring.find (v, cfg.indic_script) then -- it's ok if one of the Indic scripts position = nil; -- unset position elseif cfg.emoji_t[mw.ustring.codepoint (v, position+1)] then -- is zwj followed by a character listed in emoji{}? position = nil; -- unset position end end if position then if 'nowiki' == capture or 'math' == capture or -- nowiki and math stripmarkers (not an error condition) ('templatestyles' == capture and utilities.in_array (param, {'id', 'quote'})) then -- templatestyles stripmarker allowed in these parameters stripmarker = true; -- set a flag elseif true == stripmarker and cfg.invisible_defs.del == capture then -- because stripmakers begin and end with the delete char, assume that we've found one end of a stripmarker position = nil; -- unset else local err_msg; if capture and not (cfg.invisible_defs.del == capture or cfg.invisible_defs.zwj == capture) then err_msg = capture .. ' ' .. char_name; else err_msg = char_name .. ' ' .. 'character'; end utilities.set_message ('err_invisible_char', {err_msg, utilities.wrap_style ('parameter', param), position}); -- add error message return; -- and done with this parameter end end end end --[[-------------------< A R G U M E N T _ W R A P P E R >---------------------- Argument wrapper. This function provides support for argument mapping defined in the configuration file so that multiple names can be transparently aliased to single internal variable. ]] local function argument_wrapper ( args ) local origin = {}; return setmetatable({ ORIGIN = function ( self, k ) local dummy = self[k]; -- force the variable to be loaded. return origin[k]; end }, { __index = function ( tbl, k ) if origin[k] ~= nil then return nil; end local args, list, v = args, cfg.aliases[k]; if type( list ) == 'table' then v, origin[k] = utilities.select_one ( args, list, 'err_redundant_parameters' ); if origin[k] == nil then origin[k] = ''; -- Empty string, not nil end elseif list ~= nil then v, origin[k] = args[list], list; else -- maybe let through instead of raising an error? -- v, origin[k] = args[k], k; error( cfg.messages['unknown_argument_map'] .. ': ' .. k); end -- Empty strings, not nil; if v == nil then v = ''; origin[k] = ''; end tbl = rawset( tbl, k, v ); return v; end, }); end --[[--------------------------< N O W R A P _ D A T E >------------------------- When date is YYYY-MM-DD format wrap in nowrap span: <span ...>YYYY-MM-DD</span>. When date is DD MMMM YYYY or is MMMM DD, YYYY then wrap in nowrap span: <span ...>DD MMMM</span> YYYY or <span ...>MMMM DD,</span> YYYY DOES NOT yet support MMMM YYYY or any of the date ranges. ]] local function nowrap_date (date) local cap = ''; local cap2 = ''; if date:match("^%d%d%d%d%-%d%d%-%d%d$") then date = utilities.substitute (cfg.presentation['nowrap1'], date); elseif date:match("^%a+%s*%d%d?,%s+%d%d%d%d$") or date:match ("^%d%d?%s*%a+%s+%d%d%d%d$") then cap, cap2 = string.match (date, "^(.*)%s+(%d%d%d%d)$"); date = utilities.substitute (cfg.presentation['nowrap2'], {cap, cap2}); end return date; end --[[--------------------------< S E T _ T I T L E T Y P E >--------------------- This function sets default title types (equivalent to the citation including |type=<default value>) for those templates that have defaults. Also handles the special case where it is desirable to omit the title type from the rendered citation (|type=none). ]] local function set_titletype (cite_class, title_type) if utilities.is_set (title_type) then if 'none' == cfg.keywords_xlate[title_type] then title_type = ''; -- if |type=none then type parameter not displayed end return title_type; -- if |type= has been set to any other value use that value end return cfg.title_types [cite_class] or ''; -- set template's default title type; else empty string for concatenation end --[[--------------------------< S A F E _ J O I N >----------------------------- Joins a sequence of strings together while checking for duplicate separation characters. ]] local function safe_join( tbl, duplicate_char ) local f = {}; -- create a function table appropriate to type of 'duplicate character' if 1 == #duplicate_char then -- for single byte ASCII characters use the string library functions f.gsub = string.gsub f.match = string.match f.sub = string.sub else -- for multi-byte characters use the ustring library functions f.gsub = mw.ustring.gsub f.match = mw.ustring.match f.sub = mw.ustring.sub end local str = ''; -- the output string local comp = ''; -- what does 'comp' mean? local end_chr = ''; local trim; for _, value in ipairs( tbl ) do if value == nil then value = ''; end if str == '' then -- if output string is empty str = value; -- assign value to it (first time through the loop) elseif value ~= '' then if value:sub(1, 1) == '<' then -- special case of values enclosed in spans and other markup. comp = value:gsub( "%b<>", "" ); -- remove HTML markup (<span>string</span> -> string) else comp = value; end -- typically duplicate_char is sepc if f.sub(comp, 1, 1) == duplicate_char then -- is first character same as duplicate_char? why test first character? -- Because individual string segments often (always?) begin with terminal punct for the -- preceding segment: 'First element' .. 'sepc next element' .. etc.? trim = false; end_chr = f.sub(str, -1, -1); -- get the last character of the output string -- str = str .. "<HERE(enchr=" .. end_chr .. ")" -- debug stuff? if end_chr == duplicate_char then -- if same as separator str = f.sub(str, 1, -2); -- remove it elseif end_chr == "'" then -- if it might be wiki-markup if f.sub(str, -3, -1) == duplicate_char .. "''" then -- if last three chars of str are sepc'' str = f.sub(str, 1, -4) .. "''"; -- remove them and add back '' elseif f.sub(str, -5, -1) == duplicate_char .. "]]''" then -- if last five chars of str are sepc]]'' trim = true; -- why? why do this and next differently from previous? elseif f.sub(str, -4, -1) == duplicate_char .. "]''" then -- if last four chars of str are sepc]'' trim = true; -- same question end elseif end_chr == "]" then -- if it might be wiki-markup if f.sub(str, -3, -1) == duplicate_char .. "]]" then -- if last three chars of str are sepc]] wikilink trim = true; elseif f.sub(str, -3, -1) == duplicate_char .. '"]' then -- if last three chars of str are sepc"] quoted external link trim = true; elseif f.sub(str, -2, -1) == duplicate_char .. "]" then -- if last two chars of str are sepc] external link trim = true; elseif f.sub(str, -4, -1) == duplicate_char .. "'']" then -- normal case when |url=something & |title=Title. trim = true; end elseif end_chr == " " then -- if last char of output string is a space if f.sub(str, -2, -1) == duplicate_char .. " " then -- if last two chars of str are <sepc><space> str = f.sub(str, 1, -3); -- remove them both end end if trim then if value ~= comp then -- value does not equal comp when value contains HTML markup local dup2 = duplicate_char; if f.match(dup2, "%A" ) then dup2 = "%" .. dup2; end -- if duplicate_char not a letter then escape it value = f.gsub(value, "(%b<>)" .. dup2, "%1", 1 ) -- remove duplicate_char if it follows HTML markup else value = f.sub(value, 2, -1 ); -- remove duplicate_char when it is first character end end end str = str .. value; -- add it to the output string end end return str; end --[[--------------------------< I S _ S U F F I X >----------------------------- returns true if suffix is properly formed Jr, Sr, or ordinal in the range 1–9. Puncutation not allowed. ]] local function is_suffix (suffix) if utilities.in_array (suffix, {'Jr', 'Sr', 'Jnr', 'Snr', '1st', '2nd', '3rd'}) or suffix:match ('^%dth$') then return true; end return false; end --[[--------------------< I S _ G O O D _ V A N C _ N A M E >------------------- For Vancouver style, author/editor names are supposed to be rendered in Latin (read ASCII) characters. When a name uses characters that contain diacritical marks, those characters are to be converted to the corresponding Latin character. When a name is written using a non-Latin alphabet or logogram, that name is to be transliterated into Latin characters. The module doesn't do this so editors may/must. This test allows |first= and |last= names to contain any of the letters defined in the four Unicode Latin character sets [http://www.unicode.org/charts/PDF/U0000.pdf C0 Controls and Basic Latin] 0041–005A, 0061–007A [http://www.unicode.org/charts/PDF/U0080.pdf C1 Controls and Latin-1 Supplement] 00C0–00D6, 00D8–00F6, 00F8–00FF [http://www.unicode.org/charts/PDF/U0100.pdf Latin Extended-A] 0100–017F [http://www.unicode.org/charts/PDF/U0180.pdf Latin Extended-B] 0180–01BF, 01C4–024F |lastn= also allowed to contain hyphens, spaces, and apostrophes. (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/) |firstn= also allowed to contain hyphens, spaces, apostrophes, and periods This original test: if nil == mw.ustring.find (last, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%']*$") or nil == mw.ustring.find (first, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%'%.]+[2-6%a]*$") then was written outside of the code editor and pasted here because the code editor gets confused between character insertion point and cursor position. The test has been rewritten to use decimal character escape sequence for the individual bytes of the Unicode characters so that it is not necessary to use an external editor to maintain this code. \195\128-\195\150 – À-Ö (U+00C0–U+00D6 – C0 controls) \195\152-\195\182 – Ø-ö (U+00D8-U+00F6 – C0 controls) \195\184-\198\191 – ø-ƿ (U+00F8-U+01BF – C0 controls, Latin extended A & B) \199\132-\201\143 – DŽ-ɏ (U+01C4-U+024F – Latin extended B) ]] local function is_good_vanc_name (last, first, suffix, position) if not suffix then if first:find ('[,%s]') then -- when there is a space or comma, might be first name/initials + generational suffix first = first:match ('(.-)[,%s]+'); -- get name/initials suffix = first:match ('[,%s]+(.+)$'); -- get generational suffix end end if utilities.is_set (suffix) then if not is_suffix (suffix) then add_vanc_error (cfg.err_msg_supl.suffix, position); return false; -- not a name with an appropriate suffix end end if nil == mw.ustring.find (last, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143%-%s%']*$") or nil == mw.ustring.find (first, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143%-%s%'%.]*$") then add_vanc_error (cfg.err_msg_supl['non-Latin char'], position); return false; -- not a string of Latin characters; Vancouver requires Romanization end; return true; end --[[--------------------------< R E D U C E _ T O _ I N I T I A L S >------------------------------------------ Attempts to convert names to initials in support of |name-list-style=vanc. Names in |firstn= may be separated by spaces or hyphens, or for initials, a period. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35062/. Vancouver style requires family rank designations (Jr, II, III, etc.) to be rendered as Jr, 2nd, 3rd, etc. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35085/. This code only accepts and understands generational suffix in the Vancouver format because Roman numerals look like, and can be mistaken for, initials. This function uses ustring functions because firstname initials may be any of the Unicode Latin characters accepted by is_good_vanc_name (). ]] local function reduce_to_initials(first, position) local name, suffix = mw.ustring.match(first, "^(%u+) ([%dJS][%drndth]+)$"); if not name then -- if not initials and a suffix name = mw.ustring.match(first, "^(%u+)$"); -- is it just initials? end if name then -- if first is initials with or without suffix if 3 > mw.ustring.len (name) then -- if one or two initials if suffix then -- if there is a suffix if is_suffix (suffix) then -- is it legitimate? return first; -- one or two initials and a valid suffix so nothing to do else add_vanc_error (cfg.err_msg_supl.suffix, position); -- one or two initials with invalid suffix so error message return first; -- and return first unmolested end else return first; -- one or two initials without suffix; nothing to do end end end -- if here then name has 3 or more uppercase letters so treat them as a word local initials, names = {}, {}; -- tables to hold name parts and initials local i = 1; -- counter for number of initials names = mw.text.split (first, '[%s,]+'); -- split into a table of names and possible suffix while names[i] do -- loop through the table if 1 < i and names[i]:match ('[%dJS][%drndth]+%.?$') then -- if not the first name, and looks like a suffix (may have trailing dot) names[i] = names[i]:gsub ('%.', ''); -- remove terminal dot if present if is_suffix (names[i]) then -- if a legitimate suffix table.insert (initials, ' ' .. names[i]); -- add a separator space, insert at end of initials table break; -- and done because suffix must fall at the end of a name end -- no error message if not a suffix; possibly because of Romanization end if 3 > i then table.insert (initials, mw.ustring.sub(names[i], 1, 1)); -- insert the initial at end of initials table end i = i + 1; -- bump the counter end return table.concat(initials) -- Vancouver format does not include spaces. end --[[--------------------------< I N T E R W I K I _ P R E F I X E N _ G E T >---------------------------------- extract interwiki prefixen from <value>. Returns two one or two values: false – no prefixen nil – prefix exists but not recognized project prefix, language prefix – when value has either of: :<project>:<language>:<article> :<language>:<project>:<article> project prefix, nil – when <value> has only a known single-letter prefix nil, language prefix – when <value> has only a known language prefix accepts single-letter project prefixen: 'd' (wikidata), 's' (wikisource), and 'w' (wikipedia) prefixes; at this writing, the other single-letter prefixen (b (wikibook), c (commons), m (meta), n (wikinews), q (wikiquote), and v (wikiversity)) are not supported. ]] local function interwiki_prefixen_get (value, is_link) if not value:find (':%l+:') then -- if no prefix return false; -- abandon; boolean here to distinguish from nil fail returns later end local prefix_patterns_linked_t = { -- sequence of valid interwiki and inter project prefixen '^%[%[:([dsw]):(%l%l+):', -- wikilinked; project and language prefixes '^%[%[:(%l%l+):([dsw]):', -- wikilinked; language and project prefixes '^%[%[:([dsw]):', -- wikilinked; project prefix '^%[%[:(%l%l+):', -- wikilinked; language prefix } local prefix_patterns_unlinked_t = { -- sequence of valid interwiki and inter project prefixen '^:([dsw]):(%l%l+):', -- project and language prefixes '^:(%l%l+):([dsw]):', -- language and project prefixes '^:([dsw]):', -- project prefix '^:(%l%l+):', -- language prefix } local cap1, cap2; for _, pattern in ipairs ((is_link and prefix_patterns_linked_t) or prefix_patterns_unlinked_t) do cap1, cap2 = value:match (pattern); if cap1 then break; -- found a match so stop looking end end if cap1 and cap2 then -- when both then :project:language: or :language:project: (both forms allowed) if 1 == #cap1 then -- length == 1 then :project:language: if cfg.inter_wiki_map[cap2] then -- is language prefix in the interwiki map? return cap1, cap2; -- return interwiki project and interwiki language end else -- here when :language:project: if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map? return cap2, cap1; -- return interwiki project and interwiki language end end return nil; -- unknown interwiki language elseif not (cap1 or cap2) then -- both are nil? return nil; -- we got something that looks like a project prefix but isn't; return fail elseif 1 == #cap1 then -- here when one capture return cap1, nil; -- length is 1 so return project, nil language else -- here when one capture and its length it more than 1 if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map? return nil, cap1; -- return nil project, language end end end --[[--------------------------< L I S T _ P E O P L E >-------------------------- Formats a list of people (authors, contributors, editors, interviewers, translators) names in the list will be linked when |<name>-link= has a value |<name>-mask- does NOT have a value; masked names are presumed to have been rendered previously so should have been linked there when |<name>-mask=0, the associated name is not rendered ]] local function list_people (control, people, etal) local sep; local namesep; local format = control.format; local maximum = control.maximum; local name_list = {}; if 'vanc' == format then -- Vancouver-like name styling? sep = cfg.presentation['sep_nl_vanc']; -- name-list separator between names is a comma namesep = cfg.presentation['sep_name_vanc']; -- last/first separator is a space else sep = cfg.presentation['sep_nl']; -- name-list separator between names is a semicolon namesep = cfg.presentation['sep_name']; -- last/first separator is <comma><space> end if sep:sub (-1, -1) ~= " " then sep = sep .. " " end if utilities.is_set (maximum) and maximum < 1 then return "", 0; end -- returned 0 is for EditorCount; not used for other names for i, person in ipairs (people) do if utilities.is_set (person.last) then local mask = person.mask; local one; local sep_one = sep; if utilities.is_set (maximum) and i > maximum then etal = true; break; end if mask then local n = tonumber (mask); -- convert to a number if it can be converted; nil else if n then one = 0 ~= n and string.rep("&mdash;", n) or nil; -- make a string of (n > 0) mdashes, nil else, to replace name person.link = nil; -- don't create link to name if name is replaces with mdash string or has been set nil else one = mask; -- replace name with mask text (must include name-list separator) sep_one = " "; -- modify name-list separator end else one = person.last; -- get surname local first = person.first -- get given name if utilities.is_set (first) then if ("vanc" == format) then -- if Vancouver format one = one:gsub ('%.', ''); -- remove periods from surnames (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/) if not person.corporate and is_good_vanc_name (one, first, nil, i) then -- and name is all Latin characters; corporate authors not tested first = reduce_to_initials (first, i); -- attempt to convert first name(s) to initials end end one = one .. namesep .. first; end end if utilities.is_set (person.link) then one = utilities.make_wikilink (person.link, one); -- link author/editor end if one then -- if <one> has a value (name, mdash replacement, or mask text replacement) local proj, tag = interwiki_prefixen_get (one, true); -- get the interwiki prefixen if present if 'w' == proj and ('Wikipedia' == mw.site.namespaces.Project['name']) then proj = nil; -- for stuff like :w:de:<article>, :w is unnecessary TODO: maint cat? end if proj then proj = ({['d'] = 'Wikidata', ['s'] = 'Wikisource', ['w'] = 'Wikipedia'})[proj]; -- :w (wikipedia) for linking from a non-wikipedia project if proj then one = one .. utilities.wrap_style ('interproj', proj); -- add resized leading space, brackets, static text, language name tag = nil; -- unset; don't do both project and language end end if tag == cfg.this_wiki_code then tag = nil; -- stuff like :en:<article> at en.wiki is pointless TODO: maint cat? end if tag then local lang = cfg.lang_tag_remap[tag] or cfg.mw_languages_by_tag_t[tag]; if lang then -- error messaging done in extract_names() where we know parameter names one = one .. utilities.wrap_style ('interwiki', lang); -- add resized leading space, brackets, static text, language name end end table.insert (name_list, one); -- add it to the list of names table.insert (name_list, sep_one); -- add the proper name-list separator end end end local count = #name_list / 2; -- (number of names + number of separators) divided by 2 if 0 < count then if 1 < count and not etal then if 'amp' == format then name_list[#name_list-2] = " & "; -- replace last separator with ampersand text elseif 'and' == format then if 2 == count then name_list[#name_list-2] = cfg.presentation.sep_nl_and; -- replace last separator with 'and' text else name_list[#name_list-2] = cfg.presentation.sep_nl_end; -- replace last separator with '(sep) and' text end end end name_list[#name_list] = nil; -- erase the last separator end local result = table.concat (name_list); -- construct list if etal and utilities.is_set (result) then -- etal may be set by |display-authors=etal but we might not have a last-first list result = result .. sep .. cfg.messages['et al']; -- we've got a last-first list and etal so add et al. end return result, count; -- return name-list string and count of number of names (count used for editor names only) end --[[--------------------< M A K E _ C I T E R E F _ I D >----------------------- Generates a CITEREF anchor ID if we have at least one name or a date. Otherwise returns an empty string. namelist is one of the contributor-, author-, or editor-name lists chosen in that order. year is Year or anchor_year. ]] local function make_citeref_id (namelist, year) local names={}; -- a table for the one to four names and year for i,v in ipairs (namelist) do -- loop through the list and take up to the first four last names names[i] = v.last if i == 4 then break end -- if four then done end table.insert (names, year); -- add the year at the end local id = table.concat(names); -- concatenate names and year for CITEREF id if utilities.is_set (id) then -- if concatenation is not an empty string return "CITEREF" .. id; -- add the CITEREF portion else return ''; -- return an empty string; no reason to include CITEREF id in this citation end end --[[--------------------------< C I T E _ C L A S S _A T T R I B U T E _M A K E >------------------------------ construct <cite> tag class attribute for this citation. <cite_class> – config.CitationClass from calling template <mode> – value from |mode= parameter ]] local function cite_class_attribute_make (cite_class, mode) local class_t = {}; table.insert (class_t, 'citation'); -- required for blue highlight if 'citation' ~= cite_class then table.insert (class_t, cite_class); -- identify this template for user css table.insert (class_t, utilities.is_set (mode) and mode or 'cs1'); -- identify the citation style for user css or javascript else table.insert (class_t, utilities.is_set (mode) and mode or 'cs2'); -- identify the citation style for user css or javascript end for _, prop_key in ipairs (z.prop_keys_t) do table.insert (class_t, prop_key); -- identify various properties for user css or javascript end return table.concat (class_t, ' '); -- make a big string and done end --[[---------------------< N A M E _ H A S _ E T A L >-------------------------- Evaluates the content of name parameters (author, editor, etc.) for variations on the theme of et al. If found, the et al. is removed, a flag is set to true and the function returns the modified name and the flag. This function never sets the flag to false but returns its previous state because it may have been set by previous passes through this function or by the associated |display-<names>=etal parameter ]] local function name_has_etal (name, etal, nocat, param) if utilities.is_set (name) then -- name can be nil in which case just return local patterns = cfg.et_al_patterns; -- get patterns from configuration for _, pattern in ipairs (patterns) do -- loop through all of the patterns if name:match (pattern) then -- if this 'et al' pattern is found in name name = name:gsub (pattern, ''); -- remove the offending text etal = true; -- set flag (may have been set previously here or by |display-<names>=etal) if not nocat then -- no categorization for |vauthors= utilities.set_message ('err_etal', {param}); -- and set an error if not added end end end end return name, etal; end --[[---------------------< N A M E _ I S _ N U M E R I C >---------------------- Add maint cat when name parameter value does not contain letters. Does not catch mixed alphanumeric names so |last=A. Green (1922-1987) does not get caught in the current version of this test but |first=(1888) is caught. returns nothing ]] local function name_is_numeric (name, list_name) if utilities.is_set (name) then if mw.ustring.match (name, '^[%A]+$') then -- when name does not contain any letters utilities.set_message ('maint_numeric_names', cfg.special_case_translation [list_name]); -- add a maint cat for this template end end end --[[-----------------< N A M E _ H A S _ M U L T _ N A M E S >------------------ Evaluates the content of last/surname (authors etc.) parameters for multiple names. Multiple names are indicated if there is more than one comma or any "unescaped" semicolons. Escaped semicolons are ones used as part of selected HTML entities. If the condition is met, the function adds the multiple name maintenance category. Same test for first except that commas should not appear in given names (MOS:JR says that the generational suffix does not take a separator character). Titles, degrees, postnominals, affiliations, all normally comma separated don't belong in a citation. <name> – name parameter value <list_name> – AuthorList, EditorList, etc <limit> – number of allowed commas; 1 (default) for surnames; 0 for given names returns nothing ]] local function name_has_mult_names (name, list_name, limit) local _, commas, semicolons, nbsps; limit = limit and limit or 1; if utilities.is_set (name) then _, commas = name:gsub (',', ''); -- count the number of commas _, semicolons = name:gsub (';', ''); -- count the number of semicolons -- nbsps probably should be its own separate count rather than merged in -- some way with semicolons because Lua patterns do not support the -- grouping operator that regex does, which means there is no way to add -- more entities to escape except by adding more counts with the new -- entities _, nbsps = name:gsub ('&nbsp;',''); -- count nbsps -- There is exactly 1 semicolon per &nbsp; entity, so subtract nbsps -- from semicolons to 'escape' them. If additional entities are added, -- they also can be subtracted. if limit < commas or 0 < (semicolons - nbsps) then utilities.set_message ('maint_mult_names', cfg.special_case_translation [list_name]); -- add a maint message end end end --[=[-------------------------< I S _ G E N E R I C >---------------------------------------------------------- Compares values assigned to various parameters according to the string provided as <item> in the function call. <item> can have on of two values: 'generic_names' – for name-holding parameters: |last=, |first=, |editor-last=, etc 'generic_titles' – for |title= There are two types of generic tests. The 'accept' tests look for a pattern that should not be rejected by the 'reject' test. For example, |author=[[John Smith (author)|Smith, John]] would be rejected by the 'author' reject test. But piped wikilinks with 'author' disambiguation should not be rejected so the 'accept' test prevents that from happening. Accept tests are always performed before reject tests. Each of the 'accept' and 'reject' sequence tables hold tables for en.wiki (['en']) and local.wiki (['local']) that each can hold a test sequence table The sequence table holds, at index [1], a test pattern, and, at index [2], a boolean control value. The control value tells string.find() or mw.ustring.find() to do plain-text search (true) or a pattern search (false). The intent of all this complexity is to make these searches as fast as possible so that we don't run out of processing time on very large articles. Returns true when a reject test finds the pattern or string false when an accept test finds the pattern or string nil else ]=] local function is_generic (item, value, wiki) local test_val; local str_lower = { -- use string.lower() for en.wiki (['en']) and use mw.ustring.lower() or local.wiki (['local']) ['en'] = string.lower, ['local'] = mw.ustring.lower, } local str_find = { -- use string.find() for en.wiki (['en']) and use mw.ustring.find() or local.wiki (['local']) ['en'] = string.find, ['local'] = mw.ustring.find, } local function test (val, test_t, wiki) -- local function to do the testing; <wiki> selects lower() and find() functions val = test_t[2] and str_lower[wiki](value) or val; -- when <test_t[2]> set to 'true', plaintext search using lowercase value return str_find[wiki] (val, test_t[1], 1, test_t[2]); -- return nil when not found or matched end local test_types_t = {'accept', 'reject'}; -- test accept patterns first, then reject patterns local wikis_t = {'en', 'local'}; -- do tests for each of these keys; en.wiki first, local.wiki second for _, test_type in ipairs (test_types_t) do -- for each test type for _, generic_value in pairs (cfg.special_case_translation[item][test_type]) do -- spin through the list of generic value fragments to accept or reject for _, wiki in ipairs (wikis_t) do if generic_value[wiki] then if test (value, generic_value[wiki], wiki) then -- go do the test return ('reject' == test_type); -- param value rejected, return true; false else end end end end end end --[[--------------------------< N A M E _ I S _ G E N E R I C >------------------------------------------------ calls is_generic() to determine if <name> is a 'generic name' listed in cfg.generic_names; <name_alias> is the parameter name used in error messaging ]] local function name_is_generic (name, name_alias) if not added_generic_name_errs and is_generic ('generic_names', name) then utilities.set_message ('err_generic_name', name_alias); -- set an error message added_generic_name_errs = true; end end --[[--------------------------< N A M E _ C H E C K S >-------------------------------------------------------- This function calls various name checking functions used to validate the content of the various name-holding parameters. ]] local function name_checks (last, first, list_name, last_alias, first_alias) local accept_name; if utilities.is_set (last) then last, accept_name = utilities.has_accept_as_written (last); -- remove accept-this-as-written markup when it wraps all of <last> if not accept_name then -- <last> not wrapped in accept-as-written markup name_has_mult_names (last, list_name); -- check for multiple names in the parameter name_is_numeric (last, list_name); -- check for names that are composed of digits and punctuation name_is_generic (last, last_alias); -- check for names found in the generic names list end end if utilities.is_set (first) then first, accept_name = utilities.has_accept_as_written (first); -- remove accept-this-as-written markup when it wraps all of <first> if not accept_name then -- <first> not wrapped in accept-as-written markup name_has_mult_names (first, list_name, 0); -- check for multiple names in the parameter; 0 is number of allowed commas in a given name name_is_numeric (first, list_name); -- check for names that are composed of digits and punctuation name_is_generic (first, first_alias); -- check for names found in the generic names list end local wl_type, D = utilities.is_wikilink (first); if 0 ~= wl_type then first = D; utilities.set_message ('err_bad_paramlink', first_alias); end end return last, first; -- done end --[[----------------------< E X T R A C T _ N A M E S >------------------------- Gets name list from the input arguments Searches through args in sequential order to find |lastn= and |firstn= parameters (or their aliases), and their matching link and mask parameters. Stops searching when both |lastn= and |firstn= are not found in args after two sequential attempts: found |last1=, |last2=, and |last3= but doesn't find |last4= and |last5= then the search is done. This function emits an error message when there is a |firstn= without a matching |lastn=. When there are 'holes' in the list of last names, |last1= and |last3= are present but |last2= is missing, an error message is emitted. |lastn= is not required to have a matching |firstn=. When an author or editor parameter contains some form of 'et al.', the 'et al.' is stripped from the parameter and a flag (etal) returned that will cause list_people() to add the static 'et al.' text from Module:Citation/CS1/Configuration. This keeps 'et al.' out of the template's metadata. When this occurs, an error is emitted. ]] local function extract_names(args, list_name) local names = {}; -- table of names local last; -- individual name components local first; local link; local mask; local i = 1; -- loop counter/indexer local n = 1; -- output table indexer local count = 0; -- used to count the number of times we haven't found a |last= (or alias for authors, |editor-last or alias for editors) local etal = false; -- return value set to true when we find some form of et al. in an author parameter local last_alias, first_alias, link_alias; -- selected parameter aliases used in error messaging while true do last, last_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'err_redundant_parameters', i ); -- search through args for name components beginning at 1 first, first_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'err_redundant_parameters', i ); link, link_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ); mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i ); if last then -- error check |lastn= alias for unknown interwiki link prefix; done here because this is where we have the parameter name local project, language = interwiki_prefixen_get (last, true); -- true because we expect interwiki links in |lastn= to be wikilinked if nil == project and nil == language then -- when both are nil utilities.set_message ('err_bad_paramlink', last_alias); -- not known, emit an error message -- TODO: err_bad_interwiki? last = utilities.remove_wiki_link (last); -- remove wikilink markup; show display value only end end if link then -- error check |linkn= alias for unknown interwiki link prefix local project, language = interwiki_prefixen_get (link, false); -- false because wiki links in |author-linkn= is an error if nil == project and nil == language then -- when both are nil utilities.set_message ('err_bad_paramlink', link_alias); -- not known, emit an error message -- TODO: err_bad_interwiki? link = nil; -- unset so we don't link link_alias = nil; end end last, etal = name_has_etal (last, etal, false, last_alias); -- find and remove variations on et al. first, etal = name_has_etal (first, etal, false, first_alias); -- find and remove variations on et al. last, first = name_checks (last, first, list_name, last_alias, first_alias); -- multiple names, extraneous annotation, etc. checks if first and not last then -- if there is a firstn without a matching lastn local alias = first_alias:find ('given', 1, true) and 'given' or 'first'; -- get first or given form of the alias utilities.set_message ('err_first_missing_last', { first_alias, -- param name of alias missing its mate first_alias:gsub (alias, {['first'] = 'last', ['given'] = 'surname'}), -- make param name appropriate to the alias form }); -- add this error message elseif not first and not last then -- if both firstn and lastn aren't found, are we done? count = count + 1; -- number of times we haven't found last and first if 2 <= count then -- two missing names and we give up break; -- normal exit or there is a two-name hole in the list; can't tell which end else -- we have last with or without a first local result; link = link_title_ok (link, link_alias, last, last_alias); -- check for improper wiki-markup if first then link = link_title_ok (link, link_alias, first, first_alias); -- check for improper wiki-markup end names[n] = {last = last, first = first, link = link, mask = mask, corporate = false}; -- add this name to our names list (corporate for |vauthors= only) n = n + 1; -- point to next location in the names table if 1 == count then -- if the previous name was missing utilities.set_message ('err_missing_name', {list_name:match ("(%w+)List"):lower(), i - 1}); -- add this error message end count = 0; -- reset the counter, we're looking for two consecutive missing names end i = i + 1; -- point to next args location end return names, etal; -- all done, return our list of names and the etal flag end --[[--------------------------< N A M E _ T A G _ G E T >------------------------------------------------------ attempt to decode |language=<lang_param> and return language name and matching tag; nil else. This function looks for: <lang_param> as a tag in cfg.lang_tag_remap{} <lang_param> as a name in cfg.lang_name_remap{} <lang_param> as a name in cfg.mw_languages_by_name_t <lang_param> as a tag in cfg.mw_languages_by_tag_t when those fail, presume that <lang_param> is an IETF-like tag that MediaWiki does not recognize. Strip all script, region, variant, whatever subtags from <lang_param> to leave just a two or three character language tag and look for the new <lang_param> in cfg.mw_languages_by_tag_t{} on success, returns name (in properly capitalized form) and matching tag (in lowercase); on failure returns nil ]] local function name_tag_get (lang_param) local lang_param_lc = mw.ustring.lower (lang_param); -- use lowercase as an index into the various tables local name; local tag; name = cfg.lang_tag_remap[lang_param_lc]; -- assume <lang_param_lc> is a tag; attempt to get remapped language name if name then -- when <name>, <lang_param> is a tag for a remapped language name return name, lang_param_lc; -- so return <name> from remap and <lang_param_lc> end tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- still assuming that <lang_param_lc> is a tag; strip script, region, variant subtags name = cfg.lang_tag_remap[tag]; -- attempt to get remapped language name with language subtag only if name then -- when <name>, <tag> is a tag for a remapped language name return name, tag; -- so return <name> from remap and <tag> end if cfg.lang_name_remap[lang_param_lc] then -- not a tag, assume <lang_param_lc> is a name; attempt to get remapped language tag return cfg.lang_name_remap[lang_param_lc][1], cfg.lang_name_remap[lang_param_lc][2]; -- for this <lang_param_lc>, return a (possibly) new name and appropriate tag end tag = cfg.mw_languages_by_name_t[lang_param_lc]; -- assume that <lang_param_lc> is a language name; attempt to get its matching tag if tag then return cfg.mw_languages_by_tag_t[tag], tag; -- <lang_param_lc> is a name so return the name from the table and <tag> end name = cfg.mw_languages_by_tag_t[lang_param_lc]; -- assume that <lang_param_lc> is a tag; attempt to get its matching language name if name then return name, lang_param_lc; -- <lang_param_lc> is a tag so return it and <name> end tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- is <lang_param_lc> an IETF-like tag that MediaWiki doesn't recognize? <tag> gets the language subtag; nil else if tag then name = cfg.mw_languages_by_tag_t[tag]; -- attempt to get a language name using the shortened <tag> if name then return name, tag; -- <lang_param_lc> is an unrecognized IETF-like tag so return <name> and language subtag end end end --[[-------------------< L A N G U A G E _ P A R A M E T E R >------------------ Gets language name from a provided two- or three-character ISO 639 code. If a code is recognized by MediaWiki, use the returned name; if not, then use the value that was provided with the language parameter. When |language= contains a recognized language (either code or name), the page is assigned to the category for that code: Category:Norwegian-language sources (no). For valid three-character code languages, the page is assigned to the single category for '639-2' codes: Category:CS1 ISO 639-2 language sources. Languages that are the same as the local wiki are not categorized. MediaWiki does not recognize three-character equivalents of two-character codes: code 'ar' is recognized but code 'ara' is not. This function supports multiple languages in the form |language=nb, French, th where the language names or codes are separated from each other by commas with optional space characters. ]] local function language_parameter (lang) local tag; -- some form of IETF-like language tag; language subtag with optional region, sript, vatiant, etc subtags local lang_subtag; -- ve populates |language= with mostly unecessary region subtags the MediaWiki does not recognize; this is the base language subtag local name; -- the language name local language_list = {}; -- table of language names to be rendered local names_t = {}; -- table made from the value assigned to |language= local this_wiki_name = mw.language.fetchLanguageName (cfg.this_wiki_code, cfg.this_wiki_code); -- get this wiki's language name names_t = mw.text.split (lang, '%s*,%s*'); -- names should be a comma separated list for _, lang in ipairs (names_t) do -- reuse lang here because we don't yet know if lang is a language name or a language tag name, tag = name_tag_get (lang); -- attempt to get name/tag pair for <lang>; <name> has proper capitalization; <tag> is lowercase if utilities.is_set (tag) then lang_subtag = tag:gsub ('^(%a%a%a?)%-.*', '%1'); -- for categorization, strip any IETF-like tags from language tag if cfg.this_wiki_code ~= lang_subtag then -- when the language is not the same as this wiki's language if 2 == lang_subtag:len() then -- and is a two-character tag utilities.add_prop_cat ('foreign-lang-source', {name, tag}, lang_subtag); -- categorize it; tag appended to allow for multiple language categorization else -- or is a recognized language (but has a three-character tag) utilities.add_prop_cat ('foreign-lang-source-2', {lang_subtag}, lang_subtag); -- categorize it differently TODO: support multiple three-character tag categories per cs1|2 template? end elseif cfg.local_lang_cat_enable then -- when the language and this wiki's language are the same and categorization is enabled utilities.add_prop_cat ('local-lang-source', {name, lang_subtag}); -- categorize it end else name = lang; -- return whatever <lang> has so that we show something utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added end table.insert (language_list, name); name = ''; -- so we can reuse it end name = utilities.make_sep_list (#language_list, language_list); if (1 == #language_list) and (lang_subtag == cfg.this_wiki_code) then -- when only one language, find lang name in this wiki lang name; for |language=en-us, 'English' in 'American English' return ''; -- if one language and that language is this wiki's return an empty string (no annotation) end return (" " .. wrap_msg ('language', name)); -- otherwise wrap with '(in ...)' --[[ TODO: should only return blank or name rather than full list so we can clean up the bunched parenthetical elements Language, Type, Format ]] end --[[-----------------------< S E T _ C S _ S T Y L E >-------------------------- Gets the default CS style configuration for the given mode. Returns default separator and either postscript as passed in or the default. In CS1, the default postscript and separator are '.'. In CS2, the default postscript is the empty string and the default separator is ','. ]] local function set_cs_style (postscript, mode) if utilities.is_set(postscript) then -- emit a maintenance message if user postscript is the default cs1 postscript -- we catch the opposite case for cs2 in set_style if mode == 'cs1' and postscript == cfg.presentation['ps_' .. mode] then utilities.set_message ('maint_postscript'); end else postscript = cfg.presentation['ps_' .. mode]; end return cfg.presentation['sep_' .. mode], postscript; end --[[--------------------------< S E T _ S T Y L E >----------------------------- Sets the separator and postscript styles. Checks the |mode= first and the #invoke CitationClass second. Removes the postscript if postscript == none. ]] local function set_style (mode, postscript, cite_class) local sep; if 'cs2' == mode then sep, postscript = set_cs_style (postscript, 'cs2'); elseif 'cs1' == mode then sep, postscript = set_cs_style (postscript, 'cs1'); elseif 'citation' == cite_class then sep, postscript = set_cs_style (postscript, 'cs2'); else sep, postscript = set_cs_style (postscript, 'cs1'); end if cfg.keywords_xlate[postscript:lower()] == 'none' then -- emit a maintenance message if user postscript is the default cs2 postscript -- we catch the opposite case for cs1 in set_cs_style if 'cs2' == mode or 'citation' == cite_class then utilities.set_message ('maint_postscript'); end postscript = ''; end return sep, postscript end --[=[-------------------------< I S _ P D F >----------------------------------- Determines if a URL has the file extension that is one of the PDF file extensions used by [[MediaWiki:Common.css]] when applying the PDF icon to external links. returns true if file extension is one of the recognized extensions, else false ]=] local function is_pdf (url) return url:match ('%.pdf$') or url:match ('%.PDF$') or url:match ('%.pdf[%?#]') or url:match ('%.PDF[%?#]') or url:match ('%.PDF&#035') or url:match ('%.pdf&#035'); end --[[--------------------------< S T Y L E _ F O R M A T >----------------------- Applies CSS style to |format=, |chapter-format=, etc. Also emits an error message if the format parameter does not have a matching URL parameter. If the format parameter is not set and the URL contains a file extension that is recognized as a PDF document by MediaWiki's commons.css, this code will set the format parameter to (PDF) with the appropriate styling. ]] local function style_format (format, url, fmt_param, url_param) if utilities.is_set (format) then format = utilities.wrap_style ('format', format); -- add leading space, parentheses, resize if not utilities.is_set (url) then utilities.set_message ('err_format_missing_url', {fmt_param, url_param}); -- add an error message end elseif is_pdf (url) then -- format is not set so if URL is a PDF file then format = utilities.wrap_style ('format', 'PDF'); -- set format to PDF else format = ''; -- empty string for concatenation end return format; end --[[---------------------< G E T _ D I S P L A Y _ N A M E S >------------------ Returns a number that defines the number of names displayed for author and editor name lists and a Boolean flag to indicate when et al. should be appended to the name list. When the value assigned to |display-xxxxors= is a number greater than or equal to zero, return the number and the previous state of the 'etal' flag (false by default but may have been set to true if the name list contains some variant of the text 'et al.'). When the value assigned to |display-xxxxors= is the keyword 'etal', return a number that is one greater than the number of authors in the list and set the 'etal' flag true. This will cause the list_people() to display all of the names in the name list followed by 'et al.' In all other cases, returns nil and the previous state of the 'etal' flag. inputs: max: A['DisplayAuthors'] or A['DisplayEditors'], etc; a number or some flavor of etal count: #a or #e list_name: 'authors' or 'editors' etal: author_etal or editor_etal This function sets an error message when |display-xxxxors= value greater than or equal to number of names but not when <max> comes from {{cs1 config}} global settings. When using global settings, <param> is set to the keyword 'cs1 config' which is used to supress the normal error. Error is suppressed because it is to be expected that some citations in an article will have the same or fewer names that the limit specified in {{cs1 config}}. ]] local function get_display_names (max, count, list_name, etal, param) if utilities.is_set (max) then if 'etal' == max:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings max = count + 1; -- number of authors + 1 so display all author name plus et al. etal = true; -- overrides value set by extract_names() elseif max:match ('^%d+$') then -- if is a string of numbers max = tonumber (max); -- make it a number if (max >= count) and ('cs1 config' ~= param) then -- error when local |display-xxxxors= value greater than or equal to number of names; not an error when using global setting utilities.set_message ('err_disp_name', {param, max}); -- add error message max = nil; end else -- not a valid keyword or number utilities.set_message ('err_disp_name', {param, max}); -- add error message max = nil; -- unset; as if |display-xxxxors= had not been set end end return max, etal; end --[[----------< E X T R A _ T E X T _ I N _ P A G E _ C H E C K >--------------- Adds error if |page=, |pages=, |quote-page=, |quote-pages= has what appears to be some form of p. or pp. abbreviation in the first characters of the parameter content. check page for extraneous p, p., pp, pp., pg, pg. at start of parameter value: good pattern: '^P[^%.P%l]' matches when page begins PX or P# but not Px where x and X are letters and # is a digit bad pattern: '^[Pp][PpGg]' matches when page begins pp, pP, Pp, PP, pg, pG, Pg, PG ]] local function extra_text_in_page_check (val, name) if not val:match (cfg.vol_iss_pg_patterns.good_ppattern) then for _, pattern in ipairs (cfg.vol_iss_pg_patterns.bad_ppatterns) do -- spin through the selected sequence table of patterns if val:match (pattern) then -- when a match, error so utilities.set_message ('err_extra_text_pages', name); -- add error message return; -- and done end end end end --[[--------------------------< E X T R A _ T E X T _ I N _ V O L _ I S S _ C H E C K >------------------------ Adds error if |volume= or |issue= has what appears to be some form of redundant 'type' indicator. For |volume=: 'V.', or 'Vol.' (with or without the dot) abbreviations or 'Volume' in the first characters of the parameter content (all case insensitive). 'V' and 'v' (without the dot) are presumed to be roman numerals so are allowed. For |issue=: 'No.', 'I.', 'Iss.' (with or without the dot) abbreviations, or 'Issue' in the first characters of the parameter content (all case insensitive). Single character values ('v', 'i', 'n') allowed when not followed by separator character ('.', ':', '=', or whitespace character) – param values are trimmed of whitespace by MediaWiki before delivered to the module. <val> is |volume= or |issue= parameter value <name> is |volume= or |issue= parameter name for error message <selector> is 'v' for |volume=, 'i' for |issue= sets error message on failure; returns nothing ]] local function extra_text_in_vol_iss_check (val, name, selector) if not utilities.is_set (val) then return; end local patterns = 'v' == selector and cfg.vol_iss_pg_patterns.vpatterns or cfg.vol_iss_pg_patterns.ipatterns; local handler = 'v' == selector and 'err_extra_text_volume' or 'err_extra_text_issue'; val = val:lower(); -- force parameter value to lower case for _, pattern in ipairs (patterns) do -- spin through the selected sequence table of patterns if val:match (pattern) then -- when a match, error so utilities.set_message (handler, name); -- add error message return; -- and done end end end --[=[-------------------------< G E T _ V _ N A M E _ T A B L E >---------------------------------------------- split apart a |vauthors= or |veditors= parameter. This function allows for corporate names, wrapped in doubled parentheses to also have commas; in the old version of the code, the doubled parentheses were included in the rendered citation and in the metadata. Individual author names may be wikilinked |vauthors=Jones AB, [[E. B. White|White EB]], ((Black, Brown, and Co.)) ]=] local function get_v_name_table (vparam, output_table, output_link_table) local name_table = mw.text.split(vparam, "%s*,%s*"); -- names are separated by commas local wl_type, label, link; -- wl_type not used here; just a placeholder local i = 1; while name_table[i] do if name_table[i]:match ('^%(%(.*[^%)][^%)]$') then -- first segment of corporate with one or more commas; this segment has the opening doubled parentheses local name = name_table[i]; i = i + 1; -- bump indexer to next segment while name_table[i] do name = name .. ', ' .. name_table[i]; -- concatenate with previous segments if name_table[i]:match ('^.*%)%)$') then -- if this table member has the closing doubled parentheses break; -- and done reassembling so end i = i + 1; -- bump indexer end table.insert (output_table, name); -- and add corporate name to the output table table.insert (output_link_table, ''); -- no wikilink else wl_type, label, link = utilities.is_wikilink (name_table[i]); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]] table.insert (output_table, label); -- add this name if 1 == wl_type then table.insert (output_link_table, label); -- simple wikilink [[D]] else table.insert (output_link_table, link); -- no wikilink or [[L|D]]; add this link if there is one, else empty string end end i = i + 1; end return output_table; end --[[--------------------------< P A R S E _ V A U T H O R S _ V E D I T O R S >-------------------------------- This function extracts author / editor names from |vauthors= or |veditors= and finds matching |xxxxor-maskn= and |xxxxor-linkn= in args. It then returns a table of assembled names just as extract_names() does. Author / editor names in |vauthors= or |veditors= must be in Vancouver system style. Corporate or institutional names may sometimes be required and because such names will often fail the is_good_vanc_name() and other format compliance tests, are wrapped in doubled parentheses ((corporate name)) to suppress the format tests. Supports generational suffixes Jr, 2nd, 3rd, 4th–6th. This function sets the Vancouver error when a required comma is missing and when there is a space between an author's initials. ]] local function parse_vauthors_veditors (args, vparam, list_name) local names = {}; -- table of names assembled from |vauthors=, |author-maskn=, |author-linkn= local v_name_table = {}; local v_link_table = {}; -- when name is wikilinked, targets go in this table local etal = false; -- return value set to true when we find some form of et al. vauthors parameter local last, first, link, mask, suffix; local corporate = false; vparam, etal = name_has_etal (vparam, etal, true); -- find and remove variations on et al. do not categorize (do it here because et al. might have a period) v_name_table = get_v_name_table (vparam, v_name_table, v_link_table); -- names are separated by commas for i, v_name in ipairs(v_name_table) do first = ''; -- set to empty string for concatenation and because it may have been set for previous author/editor local accept_name; v_name, accept_name = utilities.has_accept_as_written (v_name); -- remove accept-this-as-written markup when it wraps all of <v_name> if accept_name then last = v_name; corporate = true; -- flag used in list_people() elseif string.find(v_name, "%s") then if v_name:find('[;%.]') then -- look for commonly occurring punctuation characters; add_vanc_error (cfg.err_msg_supl.punctuation, i); end local lastfirstTable = {} lastfirstTable = mw.text.split(v_name, "%s+") first = table.remove(lastfirstTable); -- removes and returns value of last element in table which should be initials or generational suffix if not mw.ustring.match (first, '^%u+$') then -- mw.ustring here so that later we will catch non-Latin characters suffix = first; -- not initials so assume that whatever we got is a generational suffix first = table.remove(lastfirstTable); -- get what should be the initials from the table end last = table.concat(lastfirstTable, ' ') -- returns a string that is the concatenation of all other names that are not initials and generational suffix if not utilities.is_set (last) then first = ''; -- unset last = v_name; -- last empty because something wrong with first add_vanc_error (cfg.err_msg_supl.name, i); end if mw.ustring.match (last, '%a+%s+%u+%s+%a+') then add_vanc_error (cfg.err_msg_supl['missing comma'], i); -- matches last II last; the case when a comma is missing end if mw.ustring.match (v_name, ' %u %u$') then -- this test is in the wrong place TODO: move or replace with a more appropriate test add_vanc_error (cfg.err_msg_supl.initials, i); -- matches a space between two initials end else last = v_name; -- last name or single corporate name? Doesn't support multiword corporate names? do we need this? end if utilities.is_set (first) then if not mw.ustring.match (first, "^%u?%u$") then -- first shall contain one or two upper-case letters, nothing else add_vanc_error (cfg.err_msg_supl.initials, i); -- too many initials; mixed case initials (which may be ok Romanization); hyphenated initials end is_good_vanc_name (last, first, suffix, i); -- check first and last before restoring the suffix which may have a non-Latin digit if utilities.is_set (suffix) then first = first .. ' ' .. suffix; -- if there was a suffix concatenate with the initials suffix = ''; -- unset so we don't add this suffix to all subsequent names end else if not corporate then is_good_vanc_name (last, '', nil, i); end end link = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ) or v_link_table[i]; mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i ); names[i] = {last = last, first = first, link = link, mask = mask, corporate = corporate}; -- add this assembled name to our names list end return names, etal; -- all done, return our list of names end --[[--------------------------< S E L E C T _ A U T H O R _ E D I T O R _ S O U R C E >------------------------ Select one of |authors=, |authorn= / |lastn / firstn=, or |vauthors= as the source of the author name list or select one of |editorn= / editor-lastn= / |editor-firstn= or |veditors= as the source of the editor name list. Only one of these appropriate three will be used. The hierarchy is: |authorn= (and aliases) highest and |authors= lowest; |editorn= (and aliases) highest and |veditors= lowest (support for |editors= withdrawn) When looking for |authorn= / |editorn= parameters, test |xxxxor1= and |xxxxor2= (and all of their aliases); stops after the second test which mimicks the test used in extract_names() when looking for a hole in the author name list. There may be a better way to do this, I just haven't discovered what that way is. Emits an error message when more than one xxxxor name source is provided. In this function, vxxxxors = vauthors or veditors; xxxxors = authors as appropriate. ]] local function select_author_editor_source (vxxxxors, xxxxors, args, list_name) local lastfirst = false; if utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 1 ) or -- do this twice in case we have a |first1= without a |last1=; this ... utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 1 ) or -- ... also catches the case where |first= is used with |vauthors= utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 2 ) or utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 2 ) then lastfirst = true; end if (utilities.is_set (vxxxxors) and true == lastfirst) or -- these are the three error conditions (utilities.is_set (vxxxxors) and utilities.is_set (xxxxors)) or (true == lastfirst and utilities.is_set (xxxxors)) then local err_name; if 'AuthorList' == list_name then -- figure out which name should be used in error message err_name = 'author'; else err_name = 'editor'; end utilities.set_message ('err_redundant_parameters', err_name .. '-name-list parameters'); -- add error message end if true == lastfirst then return 1 end; -- return a number indicating which author name source to use if utilities.is_set (vxxxxors) then return 2 end; if utilities.is_set (xxxxors) then return 3 end; return 1; -- no authors so return 1; this allows missing author name test to run in case there is a first without last end --[[--------------------------< I S _ V A L I D _ P A R A M E T E R _ V A L U E >------------------------------ This function is used to validate a parameter's assigned value for those parameters that have only a limited number of allowable values (yes, y, true, live, dead, etc.). When the parameter value has not been assigned a value (missing or empty in the source template) the function returns the value specified by ret_val. If the parameter value is one of the list of allowed values returns the translated value; else, emits an error message and returns the value specified by ret_val. TODO: explain <invert> ]] local function is_valid_parameter_value (value, name, possible, ret_val, invert) if not utilities.is_set (value) then return ret_val; -- an empty parameter is ok end if (not invert and utilities.in_array (value, possible)) then -- normal; <value> is in <possible> table return cfg.keywords_xlate[value]; -- return translation of parameter keyword elseif invert and not utilities.in_array (value, possible) then -- invert; <value> is not in <possible> table return value; -- return <value> as it is else utilities.set_message ('err_invalid_param_val', {name, value}); -- not an allowed value so add error message return ret_val; end end --[[--------------------------< T E R M I N A T E _ N A M E _ L I S T >---------------------------------------- This function terminates a name list (author, contributor, editor) with a separator character (sepc) and a space when the last character is not a sepc character or when the last three characters are not sepc followed by two closing square brackets (close of a wikilink). When either of these is true, the name_list is terminated with a single space character. ]] local function terminate_name_list (name_list, sepc) if (string.sub (name_list, -3, -1) == sepc .. '. ') then -- if already properly terminated return name_list; -- just return the name list elseif (string.sub (name_list, -1, -1) == sepc) or (string.sub (name_list, -3, -1) == sepc .. ']]') then -- if last name in list ends with sepc char return name_list .. " "; -- don't add another else return name_list .. sepc .. ' '; -- otherwise terminate the name list end end --[[-------------------------< F O R M A T _ V O L U M E _ I S S U E >----------------------------------------- returns the concatenation of the formatted volume and issue (or journal article number) parameters as a single string; or formatted volume or formatted issue, or an empty string if neither are set. ]] local function format_volume_issue (volume, issue, article, cite_class, origin, sepc, lower) if not utilities.is_set (volume) and not utilities.is_set (issue) and not utilities.is_set (article) then return ''; end -- same condition as in format_pages_sheets() local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin); local is_numeric_vol = volume and (volume:match ('^[MDCLXVI]+$') or volume:match ('^%d+$')); -- is only uppercase roman numerals or only digits? local is_long_vol = volume and (4 < mw.ustring.len(volume)); -- is |volume= value longer than 4 characters? if volume and (not is_numeric_vol and is_long_vol) then -- when not all digits or Roman numerals, is |volume= longer than 4 characters? utilities.add_prop_cat ('long-vol'); -- yes, add properties cat end if is_journal then -- journal-style formatting local vol = ''; if utilities.is_set (volume) then if is_numeric_vol then -- |volume= value all digits or all uppercase Roman numerals? vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, volume}); -- render in bold face elseif is_long_vol then -- not all digits or Roman numerals; longer than 4 characters? vol = utilities.substitute (cfg.messages['j-vol'], {sepc, utilities.hyphen_to_dash (volume)}); -- not bold else -- four or fewer characters vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, utilities.hyphen_to_dash (volume)}); -- bold end end vol = vol .. (utilities.is_set (issue) and utilities.substitute (cfg.messages['j-issue'], issue) or '') vol = vol .. (utilities.is_set (article) and utilities.substitute (cfg.messages['j-article-num'], article) or '') return vol; end if 'podcast' == cite_class and utilities.is_set (issue) then return wrap_msg ('issue', {sepc, issue}, lower); end if 'conference' == cite_class and utilities.is_set (article) then -- |article-number= supported only in journal and conference cites if utilities.is_set (volume) and utilities.is_set (article) then -- both volume and article number return wrap_msg ('vol-art', {sepc, utilities.hyphen_to_dash (volume), article}, lower); elseif utilities.is_set (article) then -- article number alone; when volume alone, handled below return wrap_msg ('art', {sepc, article}, lower); end end -- all other types of citation if utilities.is_set (volume) and utilities.is_set (issue) then return wrap_msg ('vol-no', {sepc, utilities.hyphen_to_dash (volume), issue}, lower); elseif utilities.is_set (volume) then return wrap_msg ('vol', {sepc, utilities.hyphen_to_dash (volume)}, lower); else return wrap_msg ('issue', {sepc, issue}, lower); end end --[[-------------------------< F O R M A T _ P A G E S _ S H E E T S >----------------------------------------- adds static text to one of |page(s)= or |sheet(s)= values and returns it with all of the others set to empty strings. The return order is: page, pages, sheet, sheets Singular has priority over plural when both are provided. ]] local function format_pages_sheets (page, pages, sheet, sheets, cite_class, origin, sepc, nopp, lower) if 'map' == cite_class then -- only cite map supports sheet(s) as in-source locators if utilities.is_set (sheet) then if 'journal' == origin then return '', '', wrap_msg ('j-sheet', sheet, lower), ''; else return '', '', wrap_msg ('sheet', {sepc, sheet}, lower), ''; end elseif utilities.is_set (sheets) then if 'journal' == origin then return '', '', '', wrap_msg ('j-sheets', sheets, lower); else return '', '', '', wrap_msg ('sheets', {sepc, sheets}, lower); end end end local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin); if utilities.is_set (page) then if is_journal then return utilities.substitute (cfg.messages['j-page(s)'], page), '', '', ''; elseif not nopp then return utilities.substitute (cfg.messages['p-prefix'], {sepc, page}), '', '', ''; else return utilities.substitute (cfg.messages['nopp'], {sepc, page}), '', '', ''; end elseif utilities.is_set (pages) then if is_journal then return utilities.substitute (cfg.messages['j-page(s)'], pages), '', '', ''; elseif tonumber(pages) ~= nil and not nopp then -- if pages is only digits, assume a single page number return '', utilities.substitute (cfg.messages['p-prefix'], {sepc, pages}), '', ''; elseif not nopp then return '', utilities.substitute (cfg.messages['pp-prefix'], {sepc, pages}), '', ''; else return '', utilities.substitute (cfg.messages['nopp'], {sepc, pages}), '', ''; end end return '', '', '', ''; -- return empty strings end --[[--------------------------< I N S O U R C E _ L O C _ G E T >---------------------------------------------- returns one of the in-source locators: page, pages, or at. If any of these are interwiki links to Wikisource, returns the label portion of the interwiki-link as plain text for use in COinS. This COinS thing is done because here we convert an interwiki-link to an external link and add an icon span around that; get_coins_pages() doesn't know about the span. TODO: should it? TODO: add support for sheet and sheets?; streamline; TODO: make it so that this function returns only one of the three as the single in-source (the return value assigned to a new name)? ]] local function insource_loc_get (page, page_orig, pages, pages_orig, at) local ws_url, ws_label, coins_pages, L; -- for Wikisource interwiki-links; TODO: this corrupts page metadata (span remains in place after cleanup; fix there?) if utilities.is_set (page) then if utilities.is_set (pages) or utilities.is_set (at) then pages = ''; -- unset the others at = ''; end extra_text_in_page_check (page, page_orig); -- emit error message when |page= value begins with what looks like p., pp., etc. ws_url, ws_label, L = wikisource_url_make (page); -- make ws URL from |page= interwiki link; link portion L becomes tooltip label if ws_url then page = external_link (ws_url, ws_label .. '&nbsp;', 'ws link in page'); -- space char after label to move icon away from in-source text; TODO: a better way to do this? page = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, page}); coins_pages = ws_label; end elseif utilities.is_set (pages) then if utilities.is_set (at) then at = ''; -- unset end extra_text_in_page_check (pages, pages_orig); -- emit error message when |page= value begins with what looks like p., pp., etc. ws_url, ws_label, L = wikisource_url_make (pages); -- make ws URL from |pages= interwiki link; link portion L becomes tooltip label if ws_url then pages = external_link (ws_url, ws_label .. '&nbsp;', 'ws link in pages'); -- space char after label to move icon away from in-source text; TODO: a better way to do this? pages = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, pages}); coins_pages = ws_label; end elseif utilities.is_set (at) then ws_url, ws_label, L = wikisource_url_make (at); -- make ws URL from |at= interwiki link; link portion L becomes tooltip label if ws_url then at = external_link (ws_url, ws_label .. '&nbsp;', 'ws link in at'); -- space char after label to move icon away from in-source text; TODO: a better way to do this? at = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, at}); coins_pages = ws_label; end end return page, pages, at, coins_pages; end --[[--------------------------< I S _ U N I Q U E _ A R C H I V E _ U R L >------------------------------------ add error message when |archive-url= value is same as |url= or chapter-url= (or alias...) value ]] local function is_unique_archive_url (archive, url, c_url, source, date) if utilities.is_set (archive) then if archive == url or archive == c_url then utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); -- add error message return '', ''; -- unset |archive-url= and |archive-date= because same as |url= or |chapter-url= end end return archive, date; end --[=[-------------------------< A R C H I V E _ U R L _ C H E C K >-------------------------------------------- Check archive.org URLs to make sure they at least look like they are pointing at valid archives and not to the save snapshot URL or to calendar pages. When the archive URL is 'https://web.archive.org/save/' (or http://...) archive.org saves a snapshot of the target page in the URL. That is something that Wikipedia should not allow unwitting readers to do. When the archive.org URL does not have a complete timestamp, archive.org chooses a snapshot according to its own algorithm or provides a calendar 'search' result. [[WP:ELNO]] discourages links to search results. This function looks at the value assigned to |archive-url= and returns empty strings for |archive-url= and |archive-date= and an error message when: |archive-url= holds an archive.org save command URL |archive-url= is an archive.org URL that does not have a complete timestamp (YYYYMMDDhhmmss 14 digits) in the correct place otherwise returns |archive-url= and |archive-date= There are two mostly compatible archive.org URLs: //web.archive.org/<timestamp>... -- the old form //web.archive.org/web/<timestamp>... -- the new form The old form does not support or map to the new form when it contains a display flag. There are four identified flags ('id_', 'js_', 'cs_', 'im_') but since archive.org ignores others following the same form (two letters and an underscore) we don't check for these specific flags but we do check the form. This function supports a preview mode. When the article is rendered in preview mode, this function may return a modified archive URL: for save command errors, return undated wildcard (/*/) for timestamp errors when the timestamp has a wildcard, return the URL unmodified for timestamp errors when the timestamp does not have a wildcard, return with timestamp limited to six digits plus wildcard (/yyyymm*/) A secondary function is to return an archive-url timestamp from those urls that have them (archive.org and archive.today). The timestamp is used by validation.archive_date_check() to see if the value in |archive-date= matches the timestamp in the archive url. ]=] local function archive_url_check (url, date) local err_msg = ''; -- start with the error message empty local path, timestamp, flag; -- portions of the archive.org URL timestamp = url:match ('//archive.today/(%d%d%d%d%d%d%d%d%d%d%d%d%d%d)/'); -- get timestamp from archive.today urls if timestamp then -- if this was an archive.today url ... return url, date, timestamp; -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url=, and done end -- here for archive.org urls if (not url:match('//web%.archive%.org/')) and (not url:match('//liveweb%.archive%.org/')) then -- also deprecated liveweb Wayback machine URL return url, date; -- not an archive.org archive, return ArchiveURL and ArchiveDate end if url:match('//web%.archive%.org/save/') then -- if a save command URL, we don't want to allow saving of the target page err_msg = cfg.err_msg_supl.save; url = url:gsub ('(//web%.archive%.org)/save/', '%1/*/', 1); -- for preview mode: modify ArchiveURL elseif url:match('//liveweb%.archive%.org/') then err_msg = cfg.err_msg_supl.liveweb; else path, timestamp, flag = url:match('//web%.archive%.org/([^%d]*)(%d+)([^/]*)/'); -- split out some of the URL parts for evaluation if not path then -- malformed in some way; pattern did not match err_msg = cfg.err_msg_supl.timestamp; elseif 14 ~= timestamp:len() then -- path and flag optional, must have 14-digit timestamp here err_msg = cfg.err_msg_supl.timestamp; if '*' ~= flag then local replacement = timestamp:match ('^%d%d%d%d%d%d') or timestamp:match ('^%d%d%d%d'); -- get the first 6 (YYYYMM) or first 4 digits (YYYY) if replacement then -- nil if there aren't at least 4 digits (year) replacement = replacement .. string.rep ('0', 14 - replacement:len()); -- year or yearmo (4 or 6 digits) zero-fill to make 14-digit timestamp url=url:gsub ('(//web%.archive%.org/[^%d]*)%d[^/]*', '%1' .. replacement .. '*', 1) -- for preview, modify ts to 14 digits plus splat for calendar display end end elseif utilities.is_set (path) and 'web/' ~= path then -- older archive URLs do not have the extra 'web/' path element err_msg = cfg.err_msg_supl.path; elseif utilities.is_set (flag) and not utilities.is_set (path) then -- flag not allowed with the old form URL (without the 'web/' path element) err_msg = cfg.err_msg_supl.flag; elseif utilities.is_set (flag) and not flag:match ('%a%a_') then -- flag if present must be two alpha characters and underscore (requires 'web/' path element) err_msg = cfg.err_msg_supl.flag; else return url, date, timestamp; -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url= end end -- if here, something not right so utilities.set_message ('err_archive_url', {err_msg}); -- add error message and if is_preview_mode then return url, date, timestamp; -- preview mode so return ArchiveURL, ArchiveDate, and timestamp from |archive-url= else return '', ''; -- return empty strings for ArchiveURL and ArchiveDate end end --[[--------------------------< P L A C E _ C H E C K >-------------------------------------------------------- check |place=, |publication-place=, |location= to see if these params include digits. This function added because many editors misuse location to specify the in-source location (|page(s)= and |at= are supposed to do that) returns the original parameter value without modification; added maint cat when parameter value contains digits ]] local function place_check (param_val) if not utilities.is_set (param_val) then -- parameter empty or omitted return param_val; -- return that empty state end if mw.ustring.find (param_val, '%d') then -- not empty, are there digits in the parameter value utilities.set_message ('maint_location'); -- yep, add maint cat end return param_val; -- and done end --[[--------------------------< I S _ A R C H I V E D _ C O P Y >---------------------------------------------- compares |title= to 'Archived copy' (placeholder added by bots that can't find proper title); if matches, return true; nil else ]] local function is_archived_copy (title) title = mw.ustring.lower(title); -- switch title to lower case if title:find (cfg.special_case_translation.archived_copy.en) then -- if title is 'Archived copy' return true; elseif cfg.special_case_translation.archived_copy['local'] then if mw.ustring.find (title, cfg.special_case_translation.archived_copy['local']) then -- mw.ustring() because might not be Latin script return true; end end end --[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------ This is the main function doing the majority of the citation formatting. ]] local function citation0( config, args ) --[[ Load Input Parameters The argument_wrapper facilitates the mapping of multiple aliases to single internal variable. ]] local A = argument_wrapper ( args ); local i -- Pick out the relevant fields from the arguments. Different citation templates -- define different field names for the same underlying things. local author_etal; local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors= local Authors; local NameListStyle; if cfg.global_cs1_config_t['NameListStyle'] then -- global setting in {{cs1 config}} overrides local |name-list-style= parameter value; nil when empty or assigned value invalid NameListStyle = is_valid_parameter_value (cfg.global_cs1_config_t['NameListStyle'], 'cs1 config: name-list-style', cfg.keywords_lists['name-list-style'], ''); -- error messaging 'param' here is a hoax else NameListStyle = is_valid_parameter_value (A['NameListStyle'], A:ORIGIN('NameListStyle'), cfg.keywords_lists['name-list-style'], ''); end if cfg.global_cs1_config_t['NameListStyle'] and utilities.is_set (A['NameListStyle']) then -- when template has |name-list-style=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end local Collaboration = A['Collaboration']; do -- to limit scope of selected local selected = select_author_editor_source (A['Vauthors'], A['Authors'], args, 'AuthorList'); if 1 == selected then a, author_etal = extract_names (args, 'AuthorList'); -- fetch author list from |authorn= / |lastn= / |firstn=, |author-linkn=, and |author-maskn= elseif 2 == selected then NameListStyle = 'vanc'; -- override whatever |name-list-style= might be a, author_etal = parse_vauthors_veditors (args, A['Vauthors'], 'AuthorList'); -- fetch author list from |vauthors=, |author-linkn=, and |author-maskn= elseif 3 == selected then Authors = A['Authors']; -- use content of |authors= if 'authors' == A:ORIGIN('Authors') then -- but add a maint cat if the parameter is |authors= utilities.set_message ('maint_authors'); -- because use of this parameter is discouraged; what to do about the aliases is a TODO: end end if utilities.is_set (Collaboration) then author_etal = true; -- so that |display-authors=etal not required end end local editor_etal; local e = {}; -- editors list from |editor-lastn= / |editor-firstn= pairs or |veditors= do -- to limit scope of selected local selected = select_author_editor_source (A['Veditors'], nil, args, 'EditorList'); -- support for |editors= withdrawn if 1 == selected then e, editor_etal = extract_names (args, 'EditorList'); -- fetch editor list from |editorn= / |editor-lastn= / |editor-firstn=, |editor-linkn=, and |editor-maskn= elseif 2 == selected then NameListStyle = 'vanc'; -- override whatever |name-list-style= might be e, editor_etal = parse_vauthors_veditors (args, args.veditors, 'EditorList'); -- fetch editor list from |veditors=, |editor-linkn=, and |editor-maskn= end end local Chapter = A['Chapter']; -- done here so that we have access to |contribution= from |chapter= aliases local Chapter_origin = A:ORIGIN ('Chapter'); local Contribution; -- because contribution is required for contributor(s) if 'contribution' == Chapter_origin then Contribution = Chapter; -- get the name of the contribution end local c = {}; -- contributors list from |contributor-lastn= / contributor-firstn= pairs if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (A['Periodical']) then -- |contributor= and |contribution= only supported in book cites c = extract_names (args, 'ContributorList'); -- fetch contributor list from |contributorn= / |contributor-lastn=, -firstn=, -linkn=, -maskn= if 0 < #c then if not utilities.is_set (Contribution) then -- |contributor= requires |contribution= utilities.set_message ('err_contributor_missing_required_param', 'contribution'); -- add missing contribution error message c = {}; -- blank the contributors' table; it is used as a flag later end if 0 == #a then -- |contributor= requires |author= utilities.set_message ('err_contributor_missing_required_param', 'author'); -- add missing author error message c = {}; -- blank the contributors' table; it is used as a flag later end end else -- if not a book cite if utilities.select_one (args, cfg.aliases['ContributorList-Last'], 'err_redundant_parameters', 1 ) then -- are there contributor name list parameters? utilities.set_message ('err_contributor_ignored'); -- add contributor ignored error message end Contribution = nil; -- unset end local Title = A['Title']; local TitleLink = A['TitleLink']; local auto_select = ''; -- default is auto local accept_link; TitleLink, accept_link = utilities.has_accept_as_written (TitleLink, true); -- test for accept-this-as-written markup if (not accept_link) and utilities.in_array (TitleLink, {'none', 'pmc', 'doi'}) then -- check for special keywords auto_select = TitleLink; -- remember selection for later TitleLink = ''; -- treat as if |title-link= would have been empty end TitleLink = link_title_ok (TitleLink, A:ORIGIN ('TitleLink'), Title, 'title'); -- check for wiki-markup in |title-link= or wiki-markup in |title= when |title-link= is set local Section = ''; -- {{cite map}} only; preset to empty string for concatenation if not used if 'map' == config.CitationClass and 'section' == Chapter_origin then Section = A['Chapter']; -- get |section= from |chapter= alias list; |chapter= and the other aliases not supported in {{cite map}} Chapter = ''; -- unset for now; will be reset later from |map= if present end local Periodical = A['Periodical']; local Periodical_origin = A:ORIGIN('Periodical'); local ScriptPeriodical = A['ScriptPeriodical']; local ScriptPeriodical_origin = A:ORIGIN('ScriptPeriodical'); local TransPeriodical = A['TransPeriodical']; local TransPeriodical_origin = A:ORIGIN ('TransPeriodical'); if (utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (ScriptPeriodical))) then local param; if utilities.is_set (Periodical) then -- get a parameter name from one of these periodical related meta-parameters Periodical = nil; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters param = Periodical_origin -- get parameter name for error messaging elseif utilities.is_set (TransPeriodical) then TransPeriodical = nil; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters param = TransPeriodical_origin; -- get parameter name for error messaging elseif utilities.is_set (ScriptPeriodical) then ScriptPeriodical = nil; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters param = ScriptPeriodical_origin; -- get parameter name for error messaging end if utilities.is_set (param) then -- if we found one utilities.set_message ('err_periodical_ignored', {param}); -- emit an error message end end if utilities.is_set (Periodical) then local i; Periodical, i = utilities.strip_apostrophe_markup (Periodical); -- strip apostrophe markup so that metadata isn't contaminated if i then -- non-zero when markup was stripped so emit an error message utilities.set_message ('err_apostrophe_markup', {Periodical_origin}); end end if 'mailinglist' == config.CitationClass then -- special case for {{cite mailing list}} if utilities.is_set (Periodical) and utilities.is_set (A ['MailingList']) then -- both set emit an error TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', Periodical_origin) .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'mailinglist')}); end Periodical = A ['MailingList']; -- error or no, set Periodical to |mailinglist= value because this template is {{cite mailing list}} Periodical_origin = A:ORIGIN('MailingList'); end -- web and news not tested for now because of -- Wikipedia:Administrators%27_noticeboard#Is_there_a_semi-automated_tool_that_could_fix_these_annoying_"Cite_Web"_errors? if not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) then -- 'periodical' templates require periodical parameter -- local p = {['journal'] = 'journal', ['magazine'] = 'magazine', ['news'] = 'newspaper', ['web'] = 'website'}; -- for error message local p = {['journal'] = 'journal', ['magazine'] = 'magazine'}; -- for error message if p[config.CitationClass] then utilities.set_message ('err_missing_periodical', {config.CitationClass, p[config.CitationClass]}); end end local Volume; -- local ScriptPeriodical_origin = A:ORIGIN('ScriptPeriodical'); if 'citation' == config.CitationClass then if utilities.is_set (Periodical) then if not utilities.in_array (Periodical_origin, cfg.citation_no_volume_t) then -- {{citation}} does not render |volume= when these parameters are used Volume = A['Volume']; -- but does for all other 'periodicals' end elseif utilities.is_set (ScriptPeriodical) then if 'script-website' ~= ScriptPeriodical_origin then -- {{citation}} does not render volume for |script-website= Volume = A['Volume']; -- but does for all other 'periodicals' end else Volume = A['Volume']; -- and does for non-'periodical' cites end elseif utilities.in_array (config.CitationClass, cfg.templates_using_volume) then -- render |volume= for cs1 according to the configuration settings Volume = A['Volume']; end extra_text_in_vol_iss_check (Volume, A:ORIGIN ('Volume'), 'v'); local Issue; if 'citation' == config.CitationClass then if utilities.is_set (Periodical) and utilities.in_array (Periodical_origin, cfg.citation_issue_t) then -- {{citation}} may render |issue= when these parameters are used Issue = utilities.hyphen_to_dash (A['Issue']); end elseif utilities.in_array (config.CitationClass, cfg.templates_using_issue) then -- conference & map books do not support issue; {{citation}} listed here because included in settings table if not (utilities.in_array (config.CitationClass, {'conference', 'map', 'citation'}) and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then Issue = utilities.hyphen_to_dash (A['Issue']); end end local ArticleNumber; if utilities.in_array (config.CitationClass, {'journal', 'conference'}) or ('citation' == config.CitationClass and utilities.is_set (Periodical) and 'journal' == Periodical_origin) then ArticleNumber = A['ArticleNumber']; end extra_text_in_vol_iss_check (Issue, A:ORIGIN ('Issue'), 'i'); local Page; local Pages; local At; local QuotePage; local QuotePages; if not utilities.in_array (config.CitationClass, cfg.templates_not_using_page) then -- TODO: rewrite to emit ignored parameter error message? Page = A['Page']; Pages = utilities.hyphen_to_dash (A['Pages']); At = A['At']; QuotePage = A['QuotePage']; QuotePages = utilities.hyphen_to_dash (A['QuotePages']); end local Edition = A['Edition']; local PublicationPlace = place_check (A['PublicationPlace'], A:ORIGIN('PublicationPlace')); local Place = place_check (A['Place'], A:ORIGIN('Place')); local PublisherName = A['PublisherName']; local PublisherName_origin = A:ORIGIN('PublisherName'); if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then local i = 0; PublisherName, i = utilities.strip_apostrophe_markup (PublisherName); -- strip apostrophe markup so that metadata isn't contaminated; publisher is never italicized if i and (0 < i) then -- non-zero when markup was stripped so emit an error message utilities.set_message ('err_apostrophe_markup', {PublisherName_origin}); end end if ('document' == config.CitationClass) and not utilities.is_set (PublisherName) then utilities.set_message ('err_missing_publisher', {config.CitationClass, 'publisher'}); end local Newsgroup = A['Newsgroup']; -- TODO: strip apostrophe markup? local Newsgroup_origin = A:ORIGIN('Newsgroup'); if 'newsgroup' == config.CitationClass then if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then -- general use parameter |publisher= not allowed in cite newsgroup utilities.set_message ('err_parameter_ignored', {PublisherName_origin}); end PublisherName = nil; -- ensure that this parameter is unset for the time being; will be used again after COinS end local URL = A['URL']; -- TODO: better way to do this for URL, ChapterURL, and MapURL? local UrlAccess = is_valid_parameter_value (A['UrlAccess'], A:ORIGIN('UrlAccess'), cfg.keywords_lists['url-access'], nil); if not utilities.is_set (URL) and utilities.is_set (UrlAccess) then UrlAccess = nil; utilities.set_message ('err_param_access_requires_param', 'url'); end local ChapterURL = A['ChapterURL']; local ChapterUrlAccess = is_valid_parameter_value (A['ChapterUrlAccess'], A:ORIGIN('ChapterUrlAccess'), cfg.keywords_lists['url-access'], nil); if not utilities.is_set (ChapterURL) and utilities.is_set (ChapterUrlAccess) then ChapterUrlAccess = nil; utilities.set_message ('err_param_access_requires_param', {A:ORIGIN('ChapterUrlAccess'):gsub ('%-access', '')}); end local MapUrlAccess = is_valid_parameter_value (A['MapUrlAccess'], A:ORIGIN('MapUrlAccess'), cfg.keywords_lists['url-access'], nil); if not utilities.is_set (A['MapURL']) and utilities.is_set (MapUrlAccess) then MapUrlAccess = nil; utilities.set_message ('err_param_access_requires_param', {'map-url'}); end local this_page = mw.title.getCurrentTitle(); -- also used for COinS and for language local no_tracking_cats = is_valid_parameter_value (A['NoTracking'], A:ORIGIN('NoTracking'), cfg.keywords_lists['yes_true_y'], nil); -- check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories if not utilities.is_set (no_tracking_cats) then -- ignore if we are already not going to categorize this page if cfg.uncategorized_namespaces[this_page.namespace] then -- is this page's namespace id one of the uncategorized namespace ids? no_tracking_cats = "true"; -- set no_tracking_cats end for _, v in ipairs (cfg.uncategorized_subpages) do -- cycle through page name patterns if this_page.text:match (v) then -- test page name against each pattern no_tracking_cats = "true"; -- set no_tracking_cats break; -- bail out if one is found end end end -- check for extra |page=, |pages= or |at= parameters. (also sheet and sheets while we're at it) utilities.select_one (args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'err_redundant_parameters'); -- this is a dummy call simply to get the error message and category local coins_pages; Page, Pages, At, coins_pages = insource_loc_get (Page, A:ORIGIN('Page'), Pages, A:ORIGIN('Pages'), At); local NoPP = is_valid_parameter_value (A['NoPP'], A:ORIGIN('NoPP'), cfg.keywords_lists['yes_true_y'], nil); if utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- both |publication-place= and |place= (|location=) allowed if different utilities.add_prop_cat ('location-test'); -- add property cat to evaluate how often PublicationPlace and Place are used together if PublicationPlace == Place then Place = ''; -- unset; don't need both if they are the same end elseif not utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- when only |place= (|location=) is set ... PublicationPlace = Place; -- promote |place= (|location=) to |publication-place end if PublicationPlace == Place then Place = ''; end -- don't need both if they are the same local URL_origin = A:ORIGIN('URL'); -- get name of parameter that holds URL local ChapterURL_origin = A:ORIGIN('ChapterURL'); -- get name of parameter that holds ChapterURL local ScriptChapter = A['ScriptChapter']; local ScriptChapter_origin = A:ORIGIN ('ScriptChapter'); local Format = A['Format']; local ChapterFormat = A['ChapterFormat']; local TransChapter = A['TransChapter']; local TransChapter_origin = A:ORIGIN ('TransChapter'); local TransTitle = A['TransTitle']; local ScriptTitle = A['ScriptTitle']; --[[ Parameter remapping for cite encyclopedia: When the citation has these parameters: |encyclopedia= and |title= then map |title= to |article= and |encyclopedia= to |title= for rendering |encyclopedia= and |article= then map |encyclopedia= to |title= for rendering |trans-title= maps to |trans-chapter= when |title= is re-mapped |url= maps to |chapter-url= when |title= is remapped All other combinations of |encyclopedia=, |title=, and |article= are not modified ]] local Encyclopedia = A['Encyclopedia']; -- used as a flag by this module and by ~/COinS if utilities.is_set (Encyclopedia) then -- emit error message when Encyclopedia set but template is other than {{cite encyclopedia}} or {{citation}} if 'encyclopaedia' ~= config.CitationClass and 'citation' ~= config.CitationClass then utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('Encyclopedia')}); Encyclopedia = nil; -- unset because not supported by this template end end if ('encyclopaedia' == config.CitationClass) or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then if utilities.is_set (Periodical) and utilities.is_set (Encyclopedia) then -- when both parameters set emit an error message; {{citation}} only; Periodical not allowed in {{cite encyclopedia}} utilities.set_message ('err_periodical_ignored', {Periodical_origin}); end if utilities.is_set (Encyclopedia) then Periodical = Encyclopedia; -- error or no, set Periodical to Encyclopedia for rendering; {{citation}} could (not legitimately) have both; use Encyclopedia Periodical_origin = A:ORIGIN ('Encyclopedia'); if utilities.is_set (Title) or utilities.is_set (ScriptTitle) then if not utilities.is_set (Chapter) then Chapter = Title; -- |encyclopedia= and |title= are set so map |title= to |article= and |encyclopedia= to |title= for rendering ScriptChapter = ScriptTitle; ScriptChapter_origin = A:ORIGIN('ScriptTitle') TransChapter = TransTitle; ChapterURL = URL; ChapterURL_origin = URL_origin; ChapterUrlAccess = UrlAccess; if not utilities.is_set (ChapterURL) and utilities.is_set (TitleLink) then Chapter = utilities.make_wikilink (TitleLink, Chapter); end Title = Periodical; ChapterFormat = Format; Periodical = ''; -- redundant so unset TransTitle = ''; URL = ''; Format = ''; TitleLink = ''; ScriptTitle = ''; end elseif utilities.is_set (Chapter) or utilities.is_set (ScriptChapter) then -- |title= not set Title = Periodical; -- |encyclopedia= set and |article= set so map |encyclopedia= to |title= for rendering Periodical = ''; -- redundant so unset end end end -- special case for cite techreport. local ID = A['ID']; if (config.CitationClass == "techreport") then -- special case for cite techreport if utilities.is_set (A['Number']) then -- cite techreport uses 'number', which other citations alias to 'issue' if not utilities.is_set (ID) then -- can we use ID for the "number"? ID = A['Number']; -- yes, use it else -- ID has a value so emit error message utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'id') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'number')}); end end end -- Account for the oddity that is {{cite conference}}, before generation of COinS data. local ChapterLink -- = A['ChapterLink']; -- deprecated as a parameter but still used internally by cite episode local Conference = A['Conference']; local BookTitle = A['BookTitle']; local TransTitle_origin = A:ORIGIN ('TransTitle'); if 'conference' == config.CitationClass then if utilities.is_set (BookTitle) then Chapter = Title; Chapter_origin = 'title'; -- ChapterLink = TitleLink; -- |chapter-link= is deprecated ChapterURL = URL; ChapterUrlAccess = UrlAccess; ChapterURL_origin = URL_origin; URL_origin = ''; ChapterFormat = Format; TransChapter = TransTitle; TransChapter_origin = TransTitle_origin; Title = BookTitle; Format = ''; -- TitleLink = ''; TransTitle = ''; URL = ''; end elseif 'speech' ~= config.CitationClass then Conference = ''; -- not cite conference or cite speech so make sure this is empty string end -- CS1/2 mode local Mode; if cfg.global_cs1_config_t['Mode'] then -- global setting in {{cs1 config}} overrides local |mode= parameter value; nil when empty or assigned value invalid Mode = is_valid_parameter_value (cfg.global_cs1_config_t['Mode'], 'cs1 config: mode', cfg.keywords_lists['mode'], ''); -- error messaging 'param' here is a hoax else Mode = is_valid_parameter_value (A['Mode'], A:ORIGIN('Mode'), cfg.keywords_lists['mode'], ''); end if cfg.global_cs1_config_t['Mode'] and utilities.is_set (A['Mode']) then -- when template has |mode=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end -- separator character and postscript local sepc, PostScript = set_style (Mode:lower(), A['PostScript'], config.CitationClass); -- controls capitalization of certain static text local use_lowercase = ( sepc == ',' ); -- cite map oddities local Cartography = ""; local Scale = ""; local Sheet = A['Sheet'] or ''; local Sheets = A['Sheets'] or ''; if config.CitationClass == "map" then if utilities.is_set (Chapter) then --TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'map') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', Chapter_origin)}); -- add error message end Chapter = A['Map']; Chapter_origin = A:ORIGIN('Map'); ChapterURL = A['MapURL']; ChapterURL_origin = A:ORIGIN('MapURL'); TransChapter = A['TransMap']; ScriptChapter = A['ScriptMap'] ScriptChapter_origin = A:ORIGIN('ScriptMap') ChapterUrlAccess = MapUrlAccess; ChapterFormat = A['MapFormat']; Cartography = A['Cartography']; if utilities.is_set ( Cartography ) then Cartography = sepc .. " " .. wrap_msg ('cartography', Cartography, use_lowercase); end Scale = A['Scale']; if utilities.is_set ( Scale ) then Scale = sepc .. " " .. Scale; end end -- Account for the oddities that are {{cite episode}} and {{cite serial}}, before generation of COinS data. local Series = A['Series']; if 'episode' == config.CitationClass or 'serial' == config.CitationClass then local SeriesLink = A['SeriesLink']; SeriesLink = link_title_ok (SeriesLink, A:ORIGIN ('SeriesLink'), Series, 'series'); -- check for wiki-markup in |series-link= or wiki-markup in |series= when |series-link= is set local Network = A['Network']; local Station = A['Station']; local s, n = {}, {}; -- do common parameters first if utilities.is_set (Network) then table.insert(n, Network); end if utilities.is_set (Station) then table.insert(n, Station); end ID = table.concat(n, sepc .. ' '); if 'episode' == config.CitationClass then -- handle the oddities that are strictly {{cite episode}} local Season = A['Season']; local SeriesNumber = A['SeriesNumber']; if utilities.is_set (Season) and utilities.is_set (SeriesNumber) then -- these are mutually exclusive so if both are set TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'season') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'seriesno')}); -- add error message SeriesNumber = ''; -- unset; prefer |season= over |seriesno= end -- assemble a table of parts concatenated later into Series if utilities.is_set (Season) then table.insert(s, wrap_msg ('season', Season, use_lowercase)); end if utilities.is_set (SeriesNumber) then table.insert(s, wrap_msg ('seriesnum', SeriesNumber, use_lowercase)); end if utilities.is_set (Issue) then table.insert(s, wrap_msg ('episode', Issue, use_lowercase)); end Issue = ''; -- unset because this is not a unique parameter Chapter = Title; -- promote title parameters to chapter ScriptChapter = ScriptTitle; ScriptChapter_origin = A:ORIGIN('ScriptTitle'); ChapterLink = TitleLink; -- alias |episode-link= TransChapter = TransTitle; ChapterURL = URL; ChapterUrlAccess = UrlAccess; ChapterURL_origin = URL_origin; ChapterFormat = Format; Title = Series; -- promote series to title TitleLink = SeriesLink; Series = table.concat(s, sepc .. ' '); -- this is concatenation of season, seriesno, episode number if utilities.is_set (ChapterLink) and not utilities.is_set (ChapterURL) then -- link but not URL Chapter = utilities.make_wikilink (ChapterLink, Chapter); elseif utilities.is_set (ChapterLink) and utilities.is_set (ChapterURL) then -- if both are set, URL links episode; Series = utilities.make_wikilink (ChapterLink, Series); end URL = ''; -- unset TransTitle = ''; ScriptTitle = ''; Format = ''; else -- now oddities that are cite serial Issue = ''; -- unset because this parameter no longer supported by the citation/core version of cite serial Chapter = A['Episode']; -- TODO: make |episode= available to cite episode someday? if utilities.is_set (Series) and utilities.is_set (SeriesLink) then Series = utilities.make_wikilink (SeriesLink, Series); end Series = utilities.wrap_style ('italic-title', Series); -- series is italicized end end -- end of {{cite episode}} stuff -- handle type parameter for those CS1 citations that have default values local TitleType = A['TitleType']; local Degree = A['Degree']; if utilities.in_array (config.CitationClass, {'AV-media-notes', 'document', 'interview', 'mailinglist', 'map', 'podcast', 'pressrelease', 'report', 'speech', 'techreport', 'thesis'}) then TitleType = set_titletype (config.CitationClass, TitleType); if utilities.is_set (Degree) and "Thesis" == TitleType then -- special case for cite thesis TitleType = Degree .. ' ' .. cfg.title_types ['thesis']:lower(); end end if utilities.is_set (TitleType) then -- if type parameter is specified TitleType = utilities.substitute ( cfg.messages['type'], TitleType); -- display it in parentheses -- TODO: Hack on TitleType to fix bunched parentheses problem end -- legacy: promote PublicationDate to Date if neither Date nor Year are set. local Date = A['Date']; local Date_origin; -- to hold the name of parameter promoted to Date; required for date error messaging local PublicationDate = A['PublicationDate']; local Year = A['Year']; if not utilities.is_set (Date) then Date = Year; -- promote Year to Date Year = nil; -- make nil so Year as empty string isn't used for CITEREF if not utilities.is_set (Date) and utilities.is_set (PublicationDate) then -- use PublicationDate when |date= and |year= are not set Date = PublicationDate; -- promote PublicationDate to Date PublicationDate = ''; -- unset, no longer needed Date_origin = A:ORIGIN('PublicationDate'); -- save the name of the promoted parameter else Date_origin = A:ORIGIN('Year'); -- save the name of the promoted parameter end else Date_origin = A:ORIGIN('Date'); -- not a promotion; name required for error messaging end if PublicationDate == Date then PublicationDate = ''; end -- if PublicationDate is same as Date, don't display in rendered citation --[[ Go test all of the date-holding parameters for valid MOS:DATE format and make sure that dates are real dates. This must be done before we do COinS because here is where we get the date used in the metadata. Date validation supporting code is in Module:Citation/CS1/Date_validation ]] local DF = is_valid_parameter_value (A['DF'], A:ORIGIN('DF'), cfg.keywords_lists['df'], ''); if not utilities.is_set (DF) then DF = cfg.global_df; -- local |df= if present overrides global df set by {{use xxx date}} template end local ArchiveURL; local ArchiveDate; local ArchiveFormat = A['ArchiveFormat']; local archive_url_timestamp; -- timestamp from wayback machine url ArchiveURL, ArchiveDate, archive_url_timestamp = archive_url_check (A['ArchiveURL'], A['ArchiveDate']) ArchiveFormat = style_format (ArchiveFormat, ArchiveURL, 'archive-format', 'archive-url'); ArchiveURL, ArchiveDate = is_unique_archive_url (ArchiveURL, URL, ChapterURL, A:ORIGIN('ArchiveURL'), ArchiveDate); -- add error message when URL or ChapterURL == ArchiveURL local AccessDate = A['AccessDate']; -- local LayDate = A['LayDate']; local COinS_date = {}; -- holds date info extracted from |date= for the COinS metadata by Module:Date verification local DoiBroken = A['DoiBroken']; local Embargo = A['Embargo']; local anchor_year; -- used in the CITEREF identifier do -- create defined block to contain local variables error_message, date_parameters_list, mismatch local error_message = ''; -- AirDate has been promoted to Date so not necessary to check it local date_parameters_list = { ['access-date'] = {val = AccessDate, name = A:ORIGIN ('AccessDate')}, ['archive-date'] = {val = ArchiveDate, name = A:ORIGIN ('ArchiveDate')}, ['date'] = {val = Date, name = Date_origin}, ['doi-broken-date'] = {val = DoiBroken, name = A:ORIGIN ('DoiBroken')}, ['pmc-embargo-date'] = {val = Embargo, name = A:ORIGIN ('Embargo')}, -- ['lay-date'] = {val = LayDate, name = A:ORIGIN ('LayDate')}, ['publication-date'] = {val = PublicationDate, name = A:ORIGIN ('PublicationDate')}, ['year'] = {val = Year, name = A:ORIGIN ('Year')}, }; local error_list = {}; anchor_year, Embargo = validation.dates(date_parameters_list, COinS_date, error_list); -- start temporary Julian / Gregorian calendar uncertainty categorization if COinS_date.inter_cal_cat then utilities.add_prop_cat ('jul-greg-uncertainty'); end -- end temporary Julian / Gregorian calendar uncertainty categorization if utilities.is_set (Year) and utilities.is_set (Date) then -- both |date= and |year= not normally needed; validation.year_date_check (Year, A:ORIGIN ('Year'), Date, A:ORIGIN ('Date'), error_list); end if 0 == #error_list then -- error free dates only; 0 when error_list is empty local modified = false; -- flag if utilities.is_set (DF) then -- if we need to reformat dates modified = validation.reformat_dates (date_parameters_list, DF); -- reformat to DF format, use long month names if appropriate end if true == validation.date_hyphen_to_dash (date_parameters_list) then -- convert hyphens to dashes where appropriate modified = true; utilities.set_message ('maint_date_format'); -- hyphens were converted so add maint category end -- for those wikis that can and want to have English date names translated to the local language; not supported at en.wiki if cfg.date_name_auto_xlate_enable and validation.date_name_xlate (date_parameters_list, cfg.date_digit_auto_xlate_enable ) then utilities.set_message ('maint_date_auto_xlated'); -- add maint cat modified = true; end if modified then -- if the date_parameters_list values were modified AccessDate = date_parameters_list['access-date'].val; -- overwrite date holding parameters with modified values ArchiveDate = date_parameters_list['archive-date'].val; Date = date_parameters_list['date'].val; DoiBroken = date_parameters_list['doi-broken-date'].val; -- LayDate = date_parameters_list['lay-date'].val; PublicationDate = date_parameters_list['publication-date'].val; end if archive_url_timestamp and utilities.is_set (ArchiveDate) then validation.archive_date_check (ArchiveDate, archive_url_timestamp); -- does YYYYMMDD in archive_url_timestamp match date in ArchiveDate end else utilities.set_message ('err_bad_date', {utilities.make_sep_list (#error_list, error_list)}); -- add this error message end end -- end of do if utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) or -- {{cite book}}, {{cite encyclopedia}}; TODO: {{cite conference}} and others? ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) or -- {{citation}} as an encylopedia citation ('citation' == config.CitationClass and not utilities.is_set (Periodical)) then -- {{citation}} as a book citation if utilities.is_set (PublicationPlace) then if not utilities.is_set (PublisherName) then local date = COinS_date.rftdate and tonumber (COinS_date.rftdate:match ('%d%d%d%d')); -- get year portion of COinS date (because in Arabic numerals); convert string to number if date and (1850 <= date) then -- location has no publisher; if date is 1850 or later utilities.set_message ('maint_location_no_publisher'); -- add maint cat end else -- PublisherName has a value if cfg.keywords_xlate['none'] == PublisherName then -- if that value is 'none' (only for book and encyclopedia citations) PublisherName = ''; -- unset end end end end local ID_list = {}; -- sequence table of rendered identifiers local ID_list_coins = {}; -- table of identifiers and their values from args; key is same as cfg.id_handlers's key local Class = A['Class']; -- arxiv class identifier local ID_support = { {A['ASINTLD'], 'ASIN', 'err_asintld_missing_asin', A:ORIGIN ('ASINTLD')}, {DoiBroken, 'DOI', 'err_doibroken_missing_doi', A:ORIGIN ('DoiBroken')}, {Embargo, 'PMC', 'err_embargo_missing_pmc', A:ORIGIN ('Embargo')}, } ID_list, ID_list_coins = identifiers.identifier_lists_get (args, {DoiBroken = DoiBroken, ASINTLD = A['ASINTLD'], Embargo = Embargo, Class = Class}, ID_support); -- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, {{cite ssrn}}, before generation of COinS data. if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- |arxiv= or |eprint= required for cite arxiv; |biorxiv=, |citeseerx=, |medrxiv=, |ssrn= required for their templates if not (args[cfg.id_handlers[config.CitationClass:upper()].parameters[1]] or -- can't use ID_list_coins k/v table here because invalid parameters omitted args[cfg.id_handlers[config.CitationClass:upper()].parameters[2]]) then -- which causes unexpected parameter missing error message utilities.set_message ('err_' .. config.CitationClass .. '_missing'); -- add error message end Periodical = ({['arxiv'] = 'arXiv', ['biorxiv'] = 'bioRxiv', ['citeseerx'] = 'CiteSeerX', ['medrxiv'] = 'medRxiv', ['ssrn'] = 'Social Science Research Network'})[config.CitationClass]; end -- Link the title of the work if no |url= was provided, but we have a |pmc= or a |doi= with |doi-access=free if config.CitationClass == "journal" and not utilities.is_set (URL) and not utilities.is_set (TitleLink) and not utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) then -- TODO: remove 'none' once existing citations have been switched to 'off', so 'none' can be used as token for "no title" instead if 'none' ~= cfg.keywords_xlate[auto_select] then -- if auto-linking not disabled if identifiers.auto_link_urls[auto_select] then -- manual selection URL = identifiers.auto_link_urls[auto_select]; -- set URL to be the same as identifier's external link URL_origin = cfg.id_handlers[auto_select:upper()].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title= elseif identifiers.auto_link_urls['pmc'] then -- auto-select PMC URL = identifiers.auto_link_urls['pmc']; -- set URL to be the same as the PMC external link if not embargoed URL_origin = cfg.id_handlers['PMC'].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title= elseif identifiers.auto_link_urls['doi'] then -- auto-select DOI URL = identifiers.auto_link_urls['doi']; URL_origin = cfg.id_handlers['DOI'].parameters[1]; end end if utilities.is_set (URL) then -- set when using an identifier-created URL if utilities.is_set (AccessDate) then -- |access-date= requires |url=; identifier-created URL is not |url= utilities.set_message ('err_accessdate_missing_url'); -- add an error message AccessDate = ''; -- unset end if utilities.is_set (ArchiveURL) then -- |archive-url= requires |url=; identifier-created URL is not |url= utilities.set_message ('err_archive_missing_url'); -- add an error message ArchiveURL = ''; -- unset end end end -- At this point fields may be nil if they weren't specified in the template use. We can use that fact. -- Test if citation has no title if not utilities.is_set (Title) and not utilities.is_set (TransTitle) and not utilities.is_set (ScriptTitle) then -- has special case for cite episode utilities.set_message ('err_citation_missing_title', {'episode' == config.CitationClass and 'series' or 'title'}); end if utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) and utilities.in_array (config.CitationClass, {'journal', 'citation'}) and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and ('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin) then -- special case for journal cites Title = ''; -- set title to empty string utilities.set_message ('maint_untitled'); -- add maint cat end -- COinS metadata (see <http://ocoins.info/>) for automated parsing of citation information. -- handle the oddity that is cite encyclopedia and {{citation |encyclopedia=something}}. Here we presume that -- when Periodical, Title, and Chapter are all set, then Periodical is the book (encyclopedia) title, Title -- is the article title, and Chapter is a section within the article. So, we remap local coins_chapter = Chapter; -- default assuming that remapping not required local coins_title = Title; -- et tu if 'encyclopaedia' == config.CitationClass or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then if utilities.is_set (Chapter) and utilities.is_set (Title) and utilities.is_set (Periodical) then -- if all are used then coins_chapter = Title; -- remap coins_title = Periodical; end end local coins_author = a; -- default for coins rft.au if 0 < #c then -- but if contributor list coins_author = c; -- use that instead end -- this is the function call to COinS() local OCinSoutput = metadata.COinS({ ['Periodical'] = utilities.strip_apostrophe_markup (Periodical), -- no markup in the metadata ['Encyclopedia'] = Encyclopedia, -- just a flag; content ignored by ~/COinS ['Chapter'] = metadata.make_coins_title (coins_chapter, ScriptChapter), -- Chapter and ScriptChapter stripped of bold / italic / accept-as-written markup ['Degree'] = Degree; -- cite thesis only ['Title'] = metadata.make_coins_title (coins_title, ScriptTitle), -- Title and ScriptTitle stripped of bold / italic / accept-as-written markup ['PublicationPlace'] = PublicationPlace, ['Date'] = COinS_date.rftdate, -- COinS_date.* has correctly formatted date values if Date is valid; ['Season'] = COinS_date.rftssn, ['Quarter'] = COinS_date.rftquarter, ['Chron'] = COinS_date.rftchron, ['Series'] = Series, ['Volume'] = Volume, ['Issue'] = Issue, ['ArticleNumber'] = ArticleNumber, ['Pages'] = coins_pages or metadata.get_coins_pages (first_set ({Sheet, Sheets, Page, Pages, At, QuotePage, QuotePages}, 7)), -- pages stripped of external links ['Edition'] = Edition, ['PublisherName'] = PublisherName or Newsgroup, -- any apostrophe markup already removed from PublisherName ['URL'] = first_set ({ChapterURL, URL}, 2), ['Authors'] = coins_author, ['ID_list'] = ID_list_coins, ['RawPage'] = this_page.prefixedText, }, config.CitationClass); -- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, and {{cite ssrn}} AFTER generation of COinS data. if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- we have set rft.jtitle in COinS to arXiv, bioRxiv, CiteSeerX, medRxiv, or ssrn now unset so it isn't displayed Periodical = ''; -- periodical not allowed in these templates; if article has been published, use cite journal end -- special case for cite newsgroup. Do this after COinS because we are modifying Publishername to include some static text if 'newsgroup' == config.CitationClass and utilities.is_set (Newsgroup) then PublisherName = utilities.substitute (cfg.messages['newsgroup'], external_link( 'news:' .. Newsgroup, Newsgroup, Newsgroup_origin, nil )); end local Editors; local EditorCount; -- used only for choosing {ed.) or (eds.) annotation at end of editor name-list local Contributors; -- assembled contributors name list local contributor_etal; local Translators; -- assembled translators name list local translator_etal; local t = {}; -- translators list from |translator-lastn= / translator-firstn= pairs t = extract_names (args, 'TranslatorList'); -- fetch translator list from |translatorn= / |translator-lastn=, -firstn=, -linkn=, -maskn= local Interviewers; local interviewers_list = {}; interviewers_list = extract_names (args, 'InterviewerList'); -- process preferred interviewers parameters local interviewer_etal; -- Now perform various field substitutions. -- We also add leading spaces and surrounding markup and punctuation to the -- various parts of the citation, but only when they are non-nil. do local last_first_list; local control = { format = NameListStyle, -- empty string, '&', 'amp', 'and', or 'vanc' maximum = nil, -- as if display-authors or display-editors not set mode = Mode }; do -- do editor name list first because the now unsupported coauthors used to modify control table if cfg.global_cs1_config_t['DisplayEditors'] then -- global setting from {{cs1 config}} overrides local setting control.maximum , editor_etal = get_display_names (cfg.global_cs1_config_t['DisplayEditors'], #e, 'editors', editor_etal, 'cs1 config'); else control.maximum , editor_etal = get_display_names (A['DisplayEditors'], #e, 'editors', editor_etal, A:ORIGIN ('DisplayEditors')); end if cfg.global_cs1_config_t['DisplayEditors'] and utilities.is_set (A['DisplayEditors']) then -- when template has |display-editors=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end Editors, EditorCount = list_people (control, e, editor_etal); if 1 == EditorCount and (true == editor_etal or 1 < #e) then -- only one editor displayed but includes etal then EditorCount = 2; -- spoof to display (eds.) annotation end end do -- now do interviewers if cfg.global_cs1_config_t['DisplayInterviewers'] then -- global setting from {{cs1 config}} overrides local setting control.maximum, interviewer_etal = get_display_names (cfg.global_cs1_config_t['DisplayInterviewers'], #interviewers_list, 'interviewers', interviewer_etal, 'cs1 config'); else control.maximum, interviewer_etal = get_display_names (A['DisplayInterviewers'], #interviewers_list, 'interviewers', interviewer_etal, A:ORIGIN ('DisplayInterviewers')); end if cfg.global_cs1_config_t['DisplayInterviewers'] and utilities.is_set (A['DisplayInterviewers']) then -- when template has |display-interviewers=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end Interviewers = list_people (control, interviewers_list, interviewer_etal); end do -- now do translators if cfg.global_cs1_config_t['DisplayTranslators'] then -- global setting from {{cs1 config}} overrides local setting control.maximum, translator_etal = get_display_names (cfg.global_cs1_config_t['DisplayTranslators'], #t, 'translators', translator_etal, 'cs1 config'); else control.maximum, translator_etal = get_display_names (A['DisplayTranslators'], #t, 'translators', translator_etal, A:ORIGIN ('DisplayTranslators')); end if cfg.global_cs1_config_t['DisplayTranslators'] and utilities.is_set (A['DisplayTranslators']) then -- when template has |display-translators=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end Translators = list_people (control, t, translator_etal); end do -- now do contributors if cfg.global_cs1_config_t['DisplayContributors'] then -- global setting from {{cs1 config}} overrides local setting control.maximum, contributor_etal = get_display_names (cfg.global_cs1_config_t['DisplayContributors'], #c, 'contributors', contributor_etal, 'cs1 config'); else control.maximum, contributor_etal = get_display_names (A['DisplayContributors'], #c, 'contributors', contributor_etal, A:ORIGIN ('DisplayContributors')); end if cfg.global_cs1_config_t['DisplayContributors'] and utilities.is_set (A['DisplayContributors']) then -- when template has |display-contributors=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end Contributors = list_people (control, c, contributor_etal); end do -- now do authors if cfg.global_cs1_config_t['DisplayAuthors'] then -- global setting from {{cs1 config}} overrides local setting control.maximum, author_etal = get_display_names (cfg.global_cs1_config_t['DisplayAuthors'], #a, 'authors', author_etal, 'cs1 config'); else control.maximum, author_etal = get_display_names (A['DisplayAuthors'], #a, 'authors', author_etal, A:ORIGIN ('DisplayAuthors')); end if cfg.global_cs1_config_t['DisplayAuthors'] and utilities.is_set (A['DisplayAuthors']) then -- when template has |display-authors=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end last_first_list = list_people (control, a, author_etal); if utilities.is_set (Authors) then Authors, author_etal = name_has_etal (Authors, author_etal, false, 'authors'); -- find and remove variations on et al. if author_etal then Authors = Authors .. ' ' .. cfg.messages['et al']; -- add et al. to authors parameter end else Authors = last_first_list; -- either an author name list or an empty string end end -- end of do if utilities.is_set (Authors) and utilities.is_set (Collaboration) then Authors = Authors .. ' (' .. Collaboration .. ')'; -- add collaboration after et al. end end local ConferenceFormat = A['ConferenceFormat']; local ConferenceURL = A['ConferenceURL']; ConferenceFormat = style_format (ConferenceFormat, ConferenceURL, 'conference-format', 'conference-url'); Format = style_format (Format, URL, 'format', 'url'); -- special case for chapter format so no error message or cat when chapter not supported if not (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia))) then ChapterFormat = style_format (ChapterFormat, ChapterURL, 'chapter-format', 'chapter-url'); end if not utilities.is_set (URL) then if utilities.in_array (config.CitationClass, {"web", "podcast", "mailinglist"}) or -- |url= required for cite web, cite podcast, and cite mailinglist ('citation' == config.CitationClass and ('website' == Periodical_origin or 'script-website' == ScriptPeriodical_origin)) then -- and required for {{citation}} with |website= or |script-website= utilities.set_message ('err_cite_web_url'); end -- do we have |accessdate= without either |url= or |chapter-url=? if utilities.is_set (AccessDate) and not utilities.is_set (ChapterURL) then -- ChapterURL may be set when URL is not set; utilities.set_message ('err_accessdate_missing_url'); AccessDate = ''; end end local UrlStatus = is_valid_parameter_value (A['UrlStatus'], A:ORIGIN('UrlStatus'), cfg.keywords_lists['url-status'], ''); local OriginalURL local OriginalURL_origin local OriginalFormat local OriginalAccess; UrlStatus = UrlStatus:lower(); -- used later when assembling archived text if utilities.is_set ( ArchiveURL ) then if utilities.is_set (ChapterURL) then -- if chapter-url= is set apply archive url to it OriginalURL = ChapterURL; -- save copy of source chapter's url for archive text OriginalURL_origin = ChapterURL_origin; -- name of |chapter-url= parameter for error messages OriginalFormat = ChapterFormat; -- and original |chapter-format= if 'live' ~= UrlStatus then ChapterURL = ArchiveURL -- swap-in the archive's URL ChapterURL_origin = A:ORIGIN('ArchiveURL') -- name of |archive-url= parameter for error messages ChapterFormat = ArchiveFormat or ''; -- swap in archive's format ChapterUrlAccess = nil; -- restricted access levels do not make sense for archived URLs end elseif utilities.is_set (URL) then OriginalURL = URL; -- save copy of original source URL OriginalURL_origin = URL_origin; -- name of URL parameter for error messages OriginalFormat = Format; -- and original |format= OriginalAccess = UrlAccess; if 'live' ~= UrlStatus then -- if URL set then |archive-url= applies to it URL = ArchiveURL -- swap-in the archive's URL URL_origin = A:ORIGIN('ArchiveURL') -- name of archive URL parameter for error messages Format = ArchiveFormat or ''; -- swap in archive's format UrlAccess = nil; -- restricted access levels do not make sense for archived URLs end end elseif utilities.is_set (UrlStatus) then -- if |url-status= is set when |archive-url= is not set utilities.set_message ('maint_url_status'); -- add maint cat end if utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or -- if any of the 'periodical' cites except encyclopedia ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) then local chap_param; if utilities.is_set (Chapter) then -- get a parameter name from one of these chapter related meta-parameters chap_param = A:ORIGIN ('Chapter') elseif utilities.is_set (TransChapter) then chap_param = A:ORIGIN ('TransChapter') elseif utilities.is_set (ChapterURL) then chap_param = A:ORIGIN ('ChapterURL') elseif utilities.is_set (ScriptChapter) then chap_param = ScriptChapter_origin; else utilities.is_set (ChapterFormat) chap_param = A:ORIGIN ('ChapterFormat') end if utilities.is_set (chap_param) then -- if we found one utilities.set_message ('err_chapter_ignored', {chap_param}); -- add error message Chapter = ''; -- and set them to empty string to be safe with concatenation TransChapter = ''; ChapterURL = ''; ScriptChapter = ''; ChapterFormat = ''; end else -- otherwise, format chapter / article title local no_quotes = false; -- default assume that we will be quoting the chapter parameter value if utilities.is_set (Contribution) and 0 < #c then -- if this is a contribution with contributor(s) if utilities.in_array (Contribution:lower(), cfg.keywords_lists.contribution) then -- and a generic contribution title no_quotes = true; -- then render it unquoted end end Chapter = format_chapter_title (ScriptChapter, ScriptChapter_origin, Chapter, Chapter_origin, TransChapter, TransChapter_origin, ChapterURL, ChapterURL_origin, no_quotes, ChapterUrlAccess); -- Contribution is also in Chapter if utilities.is_set (Chapter) then Chapter = Chapter .. ChapterFormat ; if 'map' == config.CitationClass and utilities.is_set (TitleType) then Chapter = Chapter .. ' ' .. TitleType; -- map annotation here; not after title end Chapter = Chapter .. sepc .. ' '; elseif utilities.is_set (ChapterFormat) then -- |chapter= not set but |chapter-format= is so ... Chapter = ChapterFormat .. sepc .. ' '; -- ... ChapterFormat has error message, we want to see it end end -- Format main title local plain_title = false; local accept_title; Title, accept_title = utilities.has_accept_as_written (Title, true); -- remove accept-this-as-written markup when it wraps all of <Title> if accept_title and ('' == Title) then -- only support forced empty for now "(())" Title = cfg.messages['notitle']; -- replace by predefined "No title" message -- TODO: utilities.set_message ( 'err_redundant_parameters', ...); -- issue proper error message instead of muting ScriptTitle = ''; -- just mute for now TransTitle = ''; -- just mute for now plain_title = true; -- suppress text decoration for descriptive title utilities.set_message ('maint_untitled'); -- add maint cat end if not accept_title then -- <Title> not wrapped in accept-as-written markup if '...' == Title:sub (-3) then -- if ellipsis is the last three characters of |title= Title = Title:gsub ('(%.%.%.)%.+$', '%1'); -- limit the number of dots to three elseif not mw.ustring.find (Title, '%.%s*%a%.$') and -- end of title is not a 'dot-(optional space-)letter-dot' initialism ... not mw.ustring.find (Title, '%s+%a%.$') then -- ...and not a 'space-letter-dot' initial (''Allium canadense'' L.) Title = mw.ustring.gsub(Title, '%' .. sepc .. '$', ''); -- remove any trailing separator character; sepc and ms.ustring() here for languages that use multibyte separator characters end if utilities.is_set (ArchiveURL) and is_archived_copy (Title) then utilities.set_message ('maint_archived_copy'); -- add maintenance category before we modify the content of Title end if is_generic ('generic_titles', Title) then utilities.set_message ('err_generic_title'); -- set an error message end end if (not plain_title) and (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'document', 'pressrelease', 'podcast', 'newsgroup', 'mailinglist', 'interview', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) or ('map' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)))) then -- special case for cite map when the map is in a periodical treat as an article Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from module provided quote marks Title = utilities.wrap_style ('quoted-title', Title); Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); elseif plain_title or ('report' == config.CitationClass) then -- no styling for cite report and descriptive titles (otherwise same as above) Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); -- for cite report, use this form for trans-title else Title = utilities.wrap_style ('italic-title', Title); Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped TransTitle = utilities.wrap_style ('trans-italic-title', TransTitle); end if utilities.is_set (TransTitle) then if utilities.is_set (Title) then TransTitle = " " .. TransTitle; else utilities.set_message ('err_trans_missing_title', {'title'}); end end if utilities.is_set (Title) then -- TODO: is this the right place to be making Wikisource URLs? if utilities.is_set (TitleLink) and utilities.is_set (URL) then utilities.set_message ('err_wikilink_in_url'); -- set an error message because we can't have both TitleLink = ''; -- unset end if not utilities.is_set (TitleLink) and utilities.is_set (URL) then Title = external_link (URL, Title, URL_origin, UrlAccess) .. TransTitle .. Format; URL = ''; -- unset these because no longer needed Format = ""; elseif utilities.is_set (TitleLink) and not utilities.is_set (URL) then local ws_url; ws_url = wikisource_url_make (TitleLink); -- ignore ws_label return; not used here if ws_url then Title = external_link (ws_url, Title .. '&nbsp;', 'ws link in title-link'); -- space char after Title to move icon away from italic text; TODO: a better way to do this? Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], TitleLink, Title}); Title = Title .. TransTitle; else Title = utilities.make_wikilink (TitleLink, Title) .. TransTitle; end else local ws_url, ws_label, L; -- Title has italic or quote markup by the time we get here which causes is_wikilink() to return 0 (not a wikilink) ws_url, ws_label, L = wikisource_url_make (Title:gsub('^[\'"]*(.-)[\'"]*$', '%1')); -- make ws URL from |title= interwiki link (strip italic or quote markup); link portion L becomes tooltip label if ws_url then Title = Title:gsub ('%b[]', ws_label); -- replace interwiki link with ws_label to retain markup Title = external_link (ws_url, Title .. '&nbsp;', 'ws link in title'); -- space char after Title to move icon away from italic text; TODO: a better way to do this? Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, Title}); Title = Title .. TransTitle; else Title = Title .. TransTitle; end end else Title = TransTitle; end if utilities.is_set (Place) then Place = " " .. wrap_msg ('written', Place, use_lowercase) .. sepc .. " "; end local ConferenceURL_origin = A:ORIGIN('ConferenceURL'); -- get name of parameter that holds ConferenceURL if utilities.is_set (Conference) then if utilities.is_set (ConferenceURL) then Conference = external_link( ConferenceURL, Conference, ConferenceURL_origin, nil ); end Conference = sepc .. " " .. Conference .. ConferenceFormat; elseif utilities.is_set (ConferenceURL) then Conference = sepc .. " " .. external_link( ConferenceURL, nil, ConferenceURL_origin, nil ); end local Position = ''; if not utilities.is_set (Position) then local Minutes = A['Minutes']; local Time = A['Time']; if utilities.is_set (Minutes) then if utilities.is_set (Time) then --TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'minutes') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'time')}); end Position = " " .. Minutes .. " " .. cfg.messages['minutes']; else if utilities.is_set (Time) then local TimeCaption = A['TimeCaption'] if not utilities.is_set (TimeCaption) then TimeCaption = cfg.messages['event']; if sepc ~= '.' then TimeCaption = TimeCaption:lower(); end end Position = " " .. TimeCaption .. " " .. Time; end end else Position = " " .. Position; At = ''; end Page, Pages, Sheet, Sheets = format_pages_sheets (Page, Pages, Sheet, Sheets, config.CitationClass, Periodical_origin, sepc, NoPP, use_lowercase); At = utilities.is_set (At) and (sepc .. " " .. At) or ""; Position = utilities.is_set (Position) and (sepc .. " " .. Position) or ""; if config.CitationClass == 'map' then local Sections = A['Sections']; -- Section (singular) is an alias of Chapter so set earlier local Inset = A['Inset']; if utilities.is_set ( Inset ) then Inset = sepc .. " " .. wrap_msg ('inset', Inset, use_lowercase); end if utilities.is_set ( Sections ) then Section = sepc .. " " .. wrap_msg ('sections', Sections, use_lowercase); elseif utilities.is_set ( Section ) then Section = sepc .. " " .. wrap_msg ('section', Section, use_lowercase); end At = At .. Inset .. Section; end local Others = A['Others']; if utilities.is_set (Others) and 0 == #a and 0 == #e then -- add maint cat when |others= has value and used without |author=, |editor= if config.CitationClass == "AV-media-notes" or config.CitationClass == "audio-visual" then -- special maint for AV/M which has a lot of 'false' positives right now utilities.set_message ('maint_others_avm') else utilities.set_message ('maint_others'); end end Others = utilities.is_set (Others) and (sepc .. " " .. Others) or ""; if utilities.is_set (Translators) then Others = safe_join ({sepc .. ' ', wrap_msg ('translated', Translators, use_lowercase), Others}, sepc); end if utilities.is_set (Interviewers) then Others = safe_join ({sepc .. ' ', wrap_msg ('interview', Interviewers, use_lowercase), Others}, sepc); end local TitleNote = A['TitleNote']; TitleNote = utilities.is_set (TitleNote) and (sepc .. " " .. TitleNote) or ""; if utilities.is_set (Edition) then if Edition:match ('%f[%a][Ee]d%n?%.?$') or Edition:match ('%f[%a][Ee]dition$') then -- Ed, ed, Ed., ed., Edn, edn, Edn., edn. utilities.set_message ('err_extra_text_edition'); -- add error message end Edition = " " .. wrap_msg ('edition', Edition); else Edition = ''; end Series = utilities.is_set (Series) and wrap_msg ('series', {sepc, Series}) or ""; -- not the same as SeriesNum local Agency = A['Agency']; Agency = utilities.is_set (Agency) and wrap_msg ('agency', {sepc, Agency}) or ""; Volume = format_volume_issue (Volume, Issue, ArticleNumber, config.CitationClass, Periodical_origin, sepc, use_lowercase); if utilities.is_set (AccessDate) then local retrv_text = " " .. cfg.messages['retrieved'] AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format if (sepc ~= ".") then retrv_text = retrv_text:lower() end -- if mode is cs2, lower case AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text AccessDate = utilities.substitute (cfg.presentation['accessdate'], {sepc, AccessDate}); -- allow editors to hide accessdates end if utilities.is_set (ID) then ID = sepc .. " " .. ID; end local Docket = A['Docket']; if "thesis" == config.CitationClass and utilities.is_set (Docket) then ID = sepc .. " Docket " .. Docket .. ID; end if "report" == config.CitationClass and utilities.is_set (Docket) then -- for cite report when |docket= is set ID = sepc .. ' ' .. Docket; -- overwrite ID even if |id= is set end if utilities.is_set (URL) then URL = " " .. external_link( URL, nil, URL_origin, UrlAccess ); end local Quote = A['Quote']; local TransQuote = A['TransQuote']; local ScriptQuote = A['ScriptQuote']; if utilities.is_set (Quote) or utilities.is_set (TransQuote) or utilities.is_set (ScriptQuote) then if utilities.is_set (Quote) then if Quote:sub(1, 1) == '"' and Quote:sub(-1, -1) == '"' then -- if first and last characters of quote are quote marks Quote = Quote:sub(2, -2); -- strip them off end end Quote = kern_quotes (Quote); -- kern if needed Quote = utilities.wrap_style ('quoted-text', Quote ); -- wrap in <q>...</q> tags if utilities.is_set (ScriptQuote) then Quote = script_concatenate (Quote, ScriptQuote, 'script-quote'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after quote is wrapped end if utilities.is_set (TransQuote) then if TransQuote:sub(1, 1) == '"' and TransQuote:sub(-1, -1) == '"' then -- if first and last characters of |trans-quote are quote marks TransQuote = TransQuote:sub(2, -2); -- strip them off end Quote = Quote .. " " .. utilities.wrap_style ('trans-quoted-title', TransQuote ); end if utilities.is_set (QuotePage) or utilities.is_set (QuotePages) then -- add page prefix local quote_prefix = ''; if utilities.is_set (QuotePage) then extra_text_in_page_check (QuotePage, 'quote-page'); -- add to maint cat if |quote-page= value begins with what looks like p., pp., etc. if not NoPP then quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePage}), '', '', ''; else quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePage}), '', '', ''; end elseif utilities.is_set (QuotePages) then extra_text_in_page_check (QuotePages, 'quote-pages'); -- add to maint cat if |quote-pages= value begins with what looks like p., pp., etc. if tonumber(QuotePages) ~= nil and not NoPP then -- if only digits, assume single page quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePages}), '', ''; elseif not NoPP then quote_prefix = utilities.substitute (cfg.messages['pp-prefix'], {sepc, QuotePages}), '', ''; else quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePages}), '', ''; end end Quote = quote_prefix .. ": " .. Quote; else Quote = sepc .. " " .. Quote; end PostScript = ""; -- cs1|2 does not supply terminal punctuation when |quote= is set end -- We check length of PostScript here because it will have been nuked by -- the quote parameters. We'd otherwise emit a message even if there wasn't -- a displayed postscript. -- TODO: Should the max size (1) be configurable? -- TODO: Should we check a specific pattern? if utilities.is_set(PostScript) and mw.ustring.len(PostScript) > 1 then utilities.set_message ('maint_postscript') end local Archived; if utilities.is_set (ArchiveURL) then if not utilities.is_set (ArchiveDate) then -- ArchiveURL set but ArchiveDate not set utilities.set_message ('err_archive_missing_date'); -- emit an error message ArchiveURL = ''; -- empty string for concatenation ArchiveDate = ''; -- empty string for concatenation end else if utilities.is_set (ArchiveDate) then -- ArchiveURL not set but ArchiveDate is set utilities.set_message ('err_archive_date_missing_url'); -- emit an error message ArchiveURL = ''; -- empty string for concatenation ArchiveDate = ''; -- empty string for concatenation end end if utilities.is_set (ArchiveURL) then local arch_text; -- if not utilities.is_set (ArchiveDate) then -- utilities.set_message ('err_archive_missing_date'); -- ArchiveDate = ''; -- empty string for concatenation -- end if "live" == UrlStatus then arch_text = cfg.messages['archived']; if sepc ~= "." then arch_text = arch_text:lower() end if utilities.is_set (ArchiveDate) then Archived = sepc .. ' ' .. utilities.substitute ( cfg.messages['archived-live'], {external_link( ArchiveURL, arch_text, A:ORIGIN('ArchiveURL'), nil) .. ArchiveFormat, ArchiveDate } ); else Archived = ''; end if not utilities.is_set (OriginalURL) then utilities.set_message ('err_archive_missing_url'); Archived = ''; -- empty string for concatenation end elseif utilities.is_set (OriginalURL) then -- UrlStatus is empty, 'dead', 'unfit', 'usurped', 'bot: unknown' if utilities.in_array (UrlStatus, {'unfit', 'usurped', 'bot: unknown'}) then arch_text = cfg.messages['archived-unfit']; if sepc ~= "." then arch_text = arch_text:lower() end Archived = sepc .. ' ' .. arch_text .. ArchiveDate; -- format already styled if 'bot: unknown' == UrlStatus then utilities.set_message ('maint_bot_unknown'); -- and add a category if not already added else utilities.set_message ('maint_unfit'); -- and add a category if not already added end else -- UrlStatus is empty, 'dead' arch_text = cfg.messages['archived-dead']; if sepc ~= "." then arch_text = arch_text:lower() end if utilities.is_set (ArchiveDate) then Archived = sepc .. " " .. utilities.substitute ( arch_text, { external_link( OriginalURL, cfg.messages['original'], OriginalURL_origin, OriginalAccess ) .. OriginalFormat, ArchiveDate } ); -- format already styled else Archived = ''; -- unset for concatenation end end else -- OriginalUrl not set utilities.set_message ('err_archive_missing_url'); Archived = ''; -- empty string for concatenation end elseif utilities.is_set (ArchiveFormat) then Archived = ArchiveFormat; -- if set and ArchiveURL not set ArchiveFormat has error message else Archived = ''; end -- local Lay = ''; -- local LaySource = A['LaySource']; -- local LayURL = A['LayURL']; -- local LayFormat = A['LayFormat']; -- LayFormat = style_format (LayFormat, LayURL, 'lay-format', 'lay-url'); -- if utilities.is_set (LayURL) then -- if utilities.is_set (LayDate) then LayDate = " (" .. LayDate .. ")" end -- if utilities.is_set (LaySource) then -- LaySource = " &ndash; ''" .. utilities.safe_for_italics (LaySource) .. "''"; -- else -- LaySource = ""; -- end -- if sepc == '.' then -- Lay = sepc .. " " .. external_link( LayURL, cfg.messages['lay summary'], A:ORIGIN('LayURL'), nil ) .. LayFormat .. LaySource .. LayDate -- else -- Lay = sepc .. " " .. external_link( LayURL, cfg.messages['lay summary']:lower(), A:ORIGIN('LayURL'), nil ) .. LayFormat .. LaySource .. LayDate -- end -- elseif utilities.is_set (LayFormat) then -- Test if |lay-format= is given without giving a |lay-url= -- Lay = sepc .. LayFormat; -- if set and LayURL not set, then LayFormat has error message -- end local TranscriptURL = A['TranscriptURL'] local TranscriptFormat = A['TranscriptFormat']; TranscriptFormat = style_format (TranscriptFormat, TranscriptURL, 'transcript-format', 'transcripturl'); local Transcript = A['Transcript']; local TranscriptURL_origin = A:ORIGIN('TranscriptURL'); -- get name of parameter that holds TranscriptURL if utilities.is_set (Transcript) then if utilities.is_set (TranscriptURL) then Transcript = external_link( TranscriptURL, Transcript, TranscriptURL_origin, nil ); end Transcript = sepc .. ' ' .. Transcript .. TranscriptFormat; elseif utilities.is_set (TranscriptURL) then Transcript = external_link( TranscriptURL, nil, TranscriptURL_origin, nil ); end local Publisher; if utilities.is_set (PublicationDate) then PublicationDate = wrap_msg ('published', PublicationDate); end if utilities.is_set (PublisherName) then if utilities.is_set (PublicationPlace) then Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate; else Publisher = sepc .. " " .. PublisherName .. PublicationDate; end elseif utilities.is_set (PublicationPlace) then Publisher= sepc .. " " .. PublicationPlace .. PublicationDate; else Publisher = PublicationDate; end -- Several of the above rely upon detecting this as nil, so do it last. if (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical)) then if utilities.is_set (Title) or utilities.is_set (TitleNote) then Periodical = sepc .. " " .. format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin); else Periodical = format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin); end end local Language = A['Language']; if utilities.is_set (Language) then Language = language_parameter (Language); -- format, categories, name from ISO639-1, etc. else Language=''; -- language not specified so make sure this is an empty string; --[[ TODO: need to extract the wrap_msg from language_parameter so that we can solve parentheses bunching problem with Format/Language/TitleType ]] end --[[ Handle the oddity that is cite speech. This code overrides whatever may be the value assigned to TitleNote (through |department=) and forces it to be " (Speech)" so that the annotation directly follows the |title= parameter value in the citation rather than the |event= parameter value (if provided). ]] if "speech" == config.CitationClass then -- cite speech only TitleNote = TitleType; -- move TitleType to TitleNote so that it renders ahead of |event= TitleType = ''; -- and unset if utilities.is_set (Periodical) then -- if Periodical, perhaps because of an included |website= or |journal= parameter if utilities.is_set (Conference) then -- and if |event= is set Conference = Conference .. sepc .. " "; -- then add appropriate punctuation to the end of the Conference variable before rendering end end end -- Piece all bits together at last. Here, all should be non-nil. -- We build things this way because it is more efficient in LUA -- not to keep reassigning to the same string variable over and over. local tcommon; local tcommon2; -- used for book cite when |contributor= is set if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then if not (utilities.is_set (Authors) or utilities.is_set (Editors)) then Others = Others:gsub ('^' .. sepc .. ' ', ''); -- when no authors and no editors, strip leading sepc and space end if utilities.is_set (Others) then Others = safe_join ({Others, sepc .. " "}, sepc) end -- add terminal punctuation & space; check for dup sepc; TODO why do we need to do this here? tcommon = safe_join( {Others, Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Edition, Publisher, Agency, Volume}, sepc ); elseif utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (Periodical) then -- special cases for book cites if utilities.is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc. tcommon = safe_join( {Title, TitleNote}, sepc ); -- author and other stuff will come after this and before tcommon2 tcommon2 = safe_join( {Conference, Periodical, Format, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc ); else tcommon = safe_join( {Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc ); end elseif 'map' == config.CitationClass then -- special cases for cite map if utilities.is_set (Chapter) then -- map in a book; TitleType is part of Chapter tcommon = safe_join( {Title, Format, Edition, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc ); elseif utilities.is_set (Periodical) then -- map in a periodical tcommon = safe_join( {Title, TitleType, Format, Periodical, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc ); else -- a sheet or stand-alone map tcommon = safe_join( {Title, TitleType, Format, Edition, Scale, Series, Language, Cartography, Others, Publisher}, sepc ); end elseif 'episode' == config.CitationClass then -- special case for cite episode tcommon = safe_join( {Title, TitleNote, TitleType, Series, Language, Edition, Publisher}, sepc ); else -- all other CS1 templates tcommon = safe_join( {Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc ); end if #ID_list > 0 then ID_list = safe_join( { sepc .. " ", table.concat( ID_list, sepc .. " " ), ID }, sepc ); else ID_list = ID; end local Via = A['Via']; Via = utilities.is_set (Via) and wrap_msg ('via', Via) or ''; local idcommon; if 'audio-visual' == config.CitationClass or 'episode' == config.CitationClass then -- special case for cite AV media & cite episode position transcript -- idcommon = safe_join( { ID_list, URL, Archived, Transcript, AccessDate, Via, Lay, Quote }, sepc ); idcommon = safe_join( { ID_list, URL, Archived, Transcript, AccessDate, Via, Quote }, sepc ); else -- idcommon = safe_join( { ID_list, URL, Archived, AccessDate, Via, Lay, Quote }, sepc ); idcommon = safe_join( { ID_list, URL, Archived, AccessDate, Via, Quote }, sepc ); end local text; local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At; local OrigDate = A['OrigDate']; OrigDate = utilities.is_set (OrigDate) and wrap_msg ('origdate', OrigDate) or ''; if utilities.is_set (Date) then if utilities.is_set (Authors) or utilities.is_set (Editors) then -- date follows authors or editors when authors not set Date = " (" .. Date .. ")" .. OrigDate .. sepc .. " "; -- in parentheses else -- neither of authors and editors set if (string.sub(tcommon, -1, -1) == sepc) then -- if the last character of tcommon is sepc Date = " " .. Date .. OrigDate; -- Date does not begin with sepc else Date = sepc .. " " .. Date .. OrigDate; -- Date begins with sepc end end end if utilities.is_set (Authors) then if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Authors termination Authors = terminate_name_list (Authors, sepc); -- when no date, terminate with 0 or 1 sepc and a space end if utilities.is_set (Editors) then local in_text = ''; local post_text = ''; if utilities.is_set (Chapter) and 0 == #c then in_text = cfg.messages['in'] .. ' '; if (sepc ~= '.') then in_text = in_text:lower(); -- lowercase for cs2 end end if EditorCount <= 1 then post_text = ' (' .. cfg.messages['editor'] .. ')'; -- be consistent with no-author, no-date case else post_text = ' (' .. cfg.messages['editors'] .. ')'; end Editors = terminate_name_list (in_text .. Editors .. post_text, sepc); -- terminate with 0 or 1 sepc and a space end if utilities.is_set (Contributors) then -- book cite and we're citing the intro, preface, etc. local by_text = sepc .. ' ' .. cfg.messages['by'] .. ' '; if (sepc ~= '.') then by_text = by_text:lower() end -- lowercase for cs2 Authors = by_text .. Authors; -- author follows title so tweak it here if utilities.is_set (Editors) and utilities.is_set (Date) then -- when Editors make sure that Authors gets terminated Authors = terminate_name_list (Authors, sepc); -- terminate with 0 or 1 sepc and a space end if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Contributors termination Contributors = terminate_name_list (Contributors, sepc); -- terminate with 0 or 1 sepc and a space end text = safe_join( {Contributors, Date, Chapter, tcommon, Authors, Place, Editors, tcommon2, pgtext, idcommon }, sepc ); else text = safe_join( {Authors, Date, Chapter, Place, Editors, tcommon, pgtext, idcommon }, sepc ); end elseif utilities.is_set (Editors) then if utilities.is_set (Date) then if EditorCount <= 1 then Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editor']; else Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editors']; end else if EditorCount <= 1 then Editors = Editors .. " (" .. cfg.messages['editor'] .. ")" .. sepc .. " " else Editors = Editors .. " (" .. cfg.messages['editors'] .. ")" .. sepc .. " " end end text = safe_join( {Editors, Date, Chapter, Place, tcommon, pgtext, idcommon}, sepc ); else if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then text = safe_join( {Chapter, Place, tcommon, pgtext, Date, idcommon}, sepc ); else text = safe_join( {Chapter, Place, tcommon, Date, pgtext, idcommon}, sepc ); end end if utilities.is_set (PostScript) and PostScript ~= sepc then text = safe_join( {text, sepc}, sepc ); -- Deals with italics, spaces, etc. text = text:sub(1, -sepc:len() - 1); end text = safe_join( {text, PostScript}, sepc ); -- Now enclose the whole thing in a <cite> element local options_t = {}; options_t.class = cite_class_attribute_make (config.CitationClass, Mode); local Ref = is_valid_parameter_value (A['Ref'], A:ORIGIN('Ref'), cfg.keywords_lists['ref'], nil, true); -- nil when |ref=harv; A['Ref'] else if 'none' ~= cfg.keywords_xlate[(Ref and Ref:lower()) or ''] then local namelist_t = {}; -- holds selected contributor, author, editor name list local year = first_set ({Year, anchor_year}, 2); -- Year first for legacy citations and for YMD dates that require disambiguation if #c > 0 then -- if there is a contributor list namelist_t = c; -- select it elseif #a > 0 then -- or an author list namelist_t = a; elseif #e > 0 then -- or an editor list namelist_t = e; end local citeref_id; if #namelist_t > 0 then -- if there are names in namelist_t citeref_id = make_citeref_id (namelist_t, year); -- go make the CITEREF anchor if mw.uri.anchorEncode (citeref_id) == ((Ref and mw.uri.anchorEncode (Ref)) or '') then -- Ref may already be encoded (by {{sfnref}}) so citeref_id must be encoded before comparison utilities.set_message ('maint_ref_duplicates_default'); end else citeref_id = ''; -- unset end options_t.id = Ref or citeref_id; end if string.len (text:gsub('%b<>', '')) <= 2 then -- remove html and html-like tags; then get length of what remains; z.error_cats_t = {}; -- blank the categories list z.error_msgs_t = {}; -- blank the error messages list OCinSoutput = nil; -- blank the metadata string text = ''; -- blank the the citation utilities.set_message ('err_empty_citation'); -- set empty citation message and category end local render_t = {}; -- here we collect the final bits for concatenation into the rendered citation if utilities.is_set (options_t.id) then -- here we wrap the rendered citation in <cite ...>...</cite> tags table.insert (render_t, utilities.substitute (cfg.presentation['cite-id'], {mw.uri.anchorEncode(options_t.id), mw.text.nowiki(options_t.class), text})); -- when |ref= is set or when there is a namelist else table.insert (render_t, utilities.substitute (cfg.presentation['cite'], {mw.text.nowiki(options_t.class), text})); -- when |ref=none or when namelist_t empty and |ref= is missing or is empty end if OCinSoutput then -- blanked when citation is 'empty' so don't bother to add boilerplate metadata span table.insert (render_t, utilities.substitute (cfg.presentation['ocins'], OCinSoutput)); -- format and append metadata to the citation end local template_name = ('citation' == config.CitationClass) and 'citation' or 'cite ' .. (cfg.citation_class_map_t[config.CitationClass] or config.CitationClass); local template_link = '[[Template:' .. template_name .. '|' .. template_name .. ']]'; local msg_prefix = '<code class="cs1-code">{{' .. template_link .. '}}</code>: '; if 0 ~= #z.error_msgs_t then mw.addWarning (utilities.substitute (cfg.messages.warning_msg_e, template_link)); table.insert (render_t, ' '); -- insert a space between citation and its error messages table.sort (z.error_msgs_t); -- sort the error messages list; sorting includes wrapping <span> and <code> tags; hidden-error sorts ahead of visible-error local hidden = true; -- presume that the only error messages emited by this template are hidden for _, v in ipairs (z.error_msgs_t) do -- spin through the list of error messages if v:find ('cs1-visible-error', 1, true) then -- look for the visible error class name hidden = false; -- found one; so don't hide the error message prefix break; -- and done because no need to look further end end z.error_msgs_t[1] = table.concat ({utilities.error_comment (msg_prefix, hidden), z.error_msgs_t[1]}); -- add error message prefix to first error message to prevent extraneous punctuation table.insert (render_t, table.concat (z.error_msgs_t, '; ')); -- make a big string of error messages and add it to the rendering end if 0 ~= #z.maint_cats_t then mw.addWarning (utilities.substitute (cfg.messages.warning_msg_m, template_link)); table.sort (z.maint_cats_t); -- sort the maintenance messages list local maint_msgs_t = {}; -- here we collect all of the maint messages if 0 == #z.error_msgs_t then -- if no error messages table.insert (maint_msgs_t, msg_prefix); -- insert message prefix in maint message livery end for _, v in ipairs( z.maint_cats_t ) do -- append maintenance categories table.insert (maint_msgs_t, -- assemble new maint message and add it to the maint_msgs_t table table.concat ({v, ' (', utilities.substitute (cfg.messages[':cat wikilink'], v), ')'}) ); end table.insert (render_t, utilities.substitute (cfg.presentation['hidden-maint'], table.concat (maint_msgs_t, ' '))); -- wrap the group of maint messages with proper presentation and save end if not no_tracking_cats then for _, v in ipairs (z.error_cats_t) do -- append error categories table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); end for _, v in ipairs (z.maint_cats_t) do -- append maintenance categories table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); end for _, v in ipairs (z.prop_cats_t) do -- append properties categories table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); end end return table.concat (render_t); -- make a big string and done end --[[--------------------------< V A L I D A T E >-------------------------------------------------------------- Looks for a parameter's name in one of several whitelists. Parameters in the whitelist can have three values: true - active, supported parameters false - deprecated, supported parameters nil - unsupported parameters ]] local function validate (name, cite_class, empty) local name = tostring (name); local enum_name; -- parameter name with enumerator (if any) replaced with '#' local state; local function state_test (state, name) -- local function to do testing of state values if true == state then return true; end -- valid actively supported parameter if false == state then if empty then return nil; end -- empty deprecated parameters are treated as unknowns deprecated_parameter (name); -- parameter is deprecated but still supported return true; end if 'tracked' == state then local base_name = name:gsub ('%d', ''); -- strip enumerators from parameter names that have them to get the base name utilities.add_prop_cat ('tracked-param', {base_name}, base_name); -- add a properties category; <base_name> modifies <key> return true; end return nil; end if name:find ('#') then -- # is a cs1|2 reserved character so parameters with # not permitted return nil; end -- replace wnumerator digit(s) with # (|last25= becomes |last#=) (mw.ustring because non-Western 'local' digits) enum_name = mw.ustring.gsub (name, '%d+$', '#'); -- where enumerator is last charaters in parameter name (these to protect |s2cid=) enum_name = mw.ustring.gsub (enum_name, '%d+([%-l])', '#%1'); -- where enumerator is in the middle of the parameter name; |author#link= is the oddity if 'document' == cite_class then -- special case for {{cite document}} state = whitelist.document_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters if true == state_test (state, name) then return true; end return false; end if utilities.in_array (cite_class, whitelist.preprint_template_list_t) then -- limited parameter sets allowed for these templates state = whitelist.limited_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters if true == state_test (state, name) then return true; end state = whitelist.preprint_arguments_t[cite_class][name]; -- look in the parameter-list for the template identified by cite_class if true == state_test (state, name) then return true; end return false; -- not supported because not found or name is set to nil end -- end limited parameter-set templates if utilities.in_array (cite_class, whitelist.unique_param_template_list_t) then -- template-specific parameters for templates that accept parameters from the basic argument list state = whitelist.unique_arguments_t[cite_class][name]; -- look in the template-specific parameter-lists for the template identified by cite_class if true == state_test (state, name) then return true; end end -- if here, fall into general validation state = whitelist.common_parameters_t[enum_name]; -- all other templates; all normal parameters allowed; this list holds enumerated and nonenumerated parameters if true == state_test (state, name) then return true; end return false; -- not supported because not found or name is set to nil end --[=[-------------------------< I N T E R _ W I K I _ C H E C K >---------------------------------------------- check <value> for inter-language interwiki-link markup. <prefix> must be a MediaWiki-recognized language code. when these values have the form (without leading colon): [[<prefix>:link|label]] return label as plain-text [[<prefix>:link]] return <prefix>:link as plain-text return value as is else ]=] local function inter_wiki_check (parameter, value) local prefix = value:match ('%[%[(%a+):'); -- get an interwiki prefix if one exists local _; if prefix and cfg.inter_wiki_map[prefix:lower()] then -- if prefix is in the map, needs preceding colon so utilities.set_message ('err_bad_paramlink', parameter); -- emit an error message _, value, _ = utilities.is_wikilink (value); -- extract label portion from wikilink end return value; end --[[--------------------------< M I S S I N G _ P I P E _ C H E C K >------------------------------------------ Look at the contents of a parameter. If the content has a string of characters and digits followed by an equal sign, compare the alphanumeric string to the list of cs1|2 parameters. If found, then the string is possibly a parameter that is missing its pipe. There are two tests made: {{cite ... |title=Title access-date=2016-03-17}} -- the first parameter has a value and whitespace separates that value from the missing pipe parameter name {{cite ... |title=access-date=2016-03-17}} -- the first parameter has no value (whitespace after the first = is trimmed by MediaWiki) cs1|2 shares some parameter names with XML/HTML attributes: class=, title=, etc. To prevent false positives XML/HTML tags are removed before the search. If a missing pipe is detected, this function adds the missing pipe maintenance category. ]] local function missing_pipe_check (parameter, value) local capture; value = value:gsub ('%b<>', ''); -- remove XML/HTML tags because attributes: class=, title=, etc. capture = value:match ('%s+(%a[%w%-]+)%s*=') or value:match ('^(%a[%w%-]+)%s*='); -- find and categorize parameters with possible missing pipes if capture and validate (capture) then -- if the capture is a valid parameter name utilities.set_message ('err_missing_pipe', parameter); end end --[[--------------------------< H A S _ E X T R A N E O U S _ P U N C T >-------------------------------------- look for extraneous terminal punctuation in most parameter values; parameters listed in skip table are not checked ]] local function has_extraneous_punc (param, value) if 'number' == type (param) then return; end param = param:gsub ('%d+', '#'); -- enumerated name-list mask params allow terminal punct; normalize if cfg.punct_skip[param] then return; -- parameter name found in the skip table so done end if value:match ('[,;:]$') then utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat end if value:match ('^=') then -- sometimes an extraneous '=' character appears ... utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat end end --[[--------------------------< H A S _ E X T R A N E O U S _ U R L >------------------------------------------ look for extraneous url parameter values; parameters listed in skip table are not checked ]] local function has_extraneous_url (url_param_t) local url_error_t = {}; check_for_url (url_param_t, url_error_t); -- extraneous url check if 0 ~= #url_error_t then -- non-zero when there are errors table.sort (url_error_t); utilities.set_message ('err_param_has_ext_link', {utilities.make_sep_list (#url_error_t, url_error_t)}); -- add this error message end end --[[--------------------------< C I T A T I O N >-------------------------------------------------------------- This is used by templates such as {{cite book}} to create the actual citation text. ]] local function citation(frame) Frame = frame; -- save a copy in case we need to display an error message in preview mode local config = {}; -- table to store parameters from the module {{#invoke:}} for k, v in pairs( frame.args ) do -- get parameters from the {{#invoke}} frame config[k] = v; -- args[k] = v; -- crude debug support that allows us to render a citation from module {{#invoke:}}; skips parameter validation; TODO: keep? end -- i18n: set the name that your wiki uses to identify sandbox subpages from sandbox template invoke (or can be set here) local sandbox = ((config.SandboxPath and '' ~= config.SandboxPath) and config.SandboxPath) or '/sandbox'; -- sandbox path from {{#invoke:Citation/CS1/sandbox|citation|SandboxPath=/...}} is_sandbox = nil ~= string.find (frame:getTitle(), sandbox, 1, true); -- is this invoke the sandbox module? sandbox = is_sandbox and sandbox or ''; -- use i18n sandbox to load sandbox modules when this module is the sandox; live modules else local pframe = frame:getParent() local styles; cfg = mw.loadData ('Module:Citation/CS1/Configuration' .. sandbox); -- load sandbox versions of support modules when {{#invoke:Citation/CS1/sandbox|...}}; live modules else whitelist = mw.loadData ('Module:Citation/CS1/Whitelist' .. sandbox); utilities = require ('Module:Citation/CS1/Utilities' .. sandbox); validation = require ('Module:Citation/CS1/Date_validation' .. sandbox); identifiers = require ('Module:Citation/CS1/Identifiers' .. sandbox); metadata = require ('Module:Citation/CS1/COinS' .. sandbox); styles = 'Module:Citation/CS1' .. sandbox .. '/styles.css'; utilities.set_selected_modules (cfg); -- so that functions in Utilities can see the selected cfg tables identifiers.set_selected_modules (cfg, utilities); -- so that functions in Identifiers can see the selected cfg tables and selected Utilities module validation.set_selected_modules (cfg, utilities); -- so that functions in Date validataion can see selected cfg tables and the selected Utilities module metadata.set_selected_modules (cfg, utilities); -- so that functions in COinS can see the selected cfg tables and selected Utilities module z = utilities.z; -- table of error and category tables in Module:Citation/CS1/Utilities is_preview_mode = not utilities.is_set (frame:preprocess ('{{REVISIONID}}')); local args = {}; -- table where we store all of the template's arguments local suggestions = {}; -- table where we store suggestions if we need to loadData them local error_text; -- used as a flag local capture; -- the single supported capture when matching unknown parameters using patterns local empty_unknowns = {}; -- sequence table to hold empty unknown params for error message listing for k, v in pairs( pframe.args ) do -- get parameters from the parent (template) frame v = mw.ustring.gsub (v, '^%s*(.-)%s*$', '%1'); -- trim leading/trailing whitespace; when v is only whitespace, becomes empty string if v ~= '' then if ('string' == type (k)) then k = mw.ustring.gsub (k, '%d', cfg.date_names.local_digits); -- for enumerated parameters, translate 'local' digits to Western 0-9 end if not validate( k, config.CitationClass ) then if type (k) ~= 'string' then -- exclude empty numbered parameters if v:match("%S+") ~= nil then error_text = utilities.set_message ('err_text_ignored', {v}); end elseif validate (k:lower(), config.CitationClass) then error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, k:lower()}); -- suggest the lowercase version of the parameter else if nil == suggestions.suggestions then -- if this table is nil then we need to load it suggestions = mw.loadData ('Module:Citation/CS1/Suggestions' .. sandbox); --load sandbox version of suggestion module when {{#invoke:Citation/CS1/sandbox|...}}; live module else end for pattern, param in pairs (suggestions.patterns) do -- loop through the patterns to see if we can suggest a proper parameter capture = k:match (pattern); -- the whole match if no capture in pattern else the capture if a match if capture then -- if the pattern matches param = utilities.substitute (param, capture); -- add the capture to the suggested parameter (typically the enumerator) if validate (param, config.CitationClass) then -- validate the suggestion to make sure that the suggestion is supported by this template (necessary for limited parameter lists) error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, param}); -- set the suggestion error message else error_text = utilities.set_message ('err_parameter_ignored', {k}); -- suggested param not supported by this template v = ''; -- unset end end end if not utilities.is_set (error_text) then -- couldn't match with a pattern, is there an explicit suggestion? if (suggestions.suggestions[ k:lower() ] ~= nil) and validate (suggestions.suggestions[ k:lower() ], config.CitationClass) then utilities.set_message ('err_parameter_ignored_suggest', {k, suggestions.suggestions[ k:lower() ]}); else utilities.set_message ('err_parameter_ignored', {k}); v = ''; -- unset value assigned to unrecognized parameters (this for the limited parameter lists) end end end end args[k] = v; -- save this parameter and its value elseif not utilities.is_set (v) then -- for empty parameters if not validate (k, config.CitationClass, true) then -- is this empty parameter a valid parameter k = ('' == k) and '(empty string)' or k; -- when k is empty string (or was space(s) trimmed to empty string), replace with descriptive text table.insert (empty_unknowns, utilities.wrap_style ('parameter', k)); -- format for error message and add to the list end -- crude debug support that allows us to render a citation from module {{#invoke:}} TODO: keep? -- elseif args[k] ~= nil or (k == 'postscript') then -- when args[k] has a value from {{#invoke}} frame (we don't normally do that) -- args[k] = v; -- overwrite args[k] with empty string from pframe.args[k] (template frame); v is empty string here end -- not sure about the postscript bit; that gets handled in parameter validation; historical artifact? end if 0 ~= #empty_unknowns then -- create empty unknown error message utilities.set_message ('err_param_unknown_empty', { 1 == #empty_unknowns and '' or 's', utilities.make_sep_list (#empty_unknowns, empty_unknowns) }); end local url_param_t = {}; for k, v in pairs( args ) do if 'string' == type (k) then -- don't evaluate positional parameters has_invisible_chars (k, v); -- look for invisible characters end has_extraneous_punc (k, v); -- look for extraneous terminal punctuation in parameter values missing_pipe_check (k, v); -- do we think that there is a parameter that is missing a pipe? args[k] = inter_wiki_check (k, v); -- when language interwiki-linked parameter missing leading colon replace with wiki-link label if 'string' == type (k) and not cfg.url_skip[k] then -- when parameter k is not positional and not in url skip table url_param_t[k] = v; -- make a parameter/value list for extraneous url check end end has_extraneous_url (url_param_t); -- look for url in parameter values where a url does not belong return table.concat ({ frame:extensionTag ('templatestyles', '', {src=styles}), citation0( config, args) }); end --[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------ ]] return {citation = citation}; 03d0c65e9544044eef296e124f940c7cc9319972 สภานิติบัญญัติแห่งชาติ พ.ศ. 2566 0 68 126 2023-10-05T15:24:45Z PeachFullzZ 2 สร้างหน้าด้วย "{{กล่องข้อมูล สภานิติบัญญัติ}} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตามรัฐธรรมนูญแห่งราชอาณาจักรไทย พุท..." wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ}} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564|รัฐธรรมนูญ พ.ศ. 2564]] d2edbfee4152995f1b5856f69cbc5bdf47636850 144 126 2023-10-05T15:56:12Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ | name = สภานิติบัญญัติแห่งชาติ | coa_pic = | coa_res = | session_room = | session_res = | house_type = ระบบสภาเดียว | houses = | leader1_type = [[ประธานสภานิติบัญญัติแห่งชาติ|ประธาน]] | leader1 = [[เนติวิทย์ นวโชติ]] | party1 = | election1 = | leader2_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 1]] | leader2 = [[โฆษิต นวชาติ]] | party2 = | election2 = | leader3_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 2]] | leader3 = [[ณิชานันท์ ธนินทวรานนท์]] | party3 = | election3 = | members = 39 ที่นั่ง |structure1 = |structure1_res = 270px | house1 = | house2 = | political_groups1 = ได้รับการแต่งตั้งมาจากภาคส่วนต่าง ๆ<br />{{colorbox|#006400}} [[บริษัท วานิเฉียนกรุป จำกัด]] (10)<br /> {{colorbox|#964B00}} [[พรรคสมัยใหม่]] (8)<br /> {{colorbox|#FF0000}} [[นักการเมืองอิสระ|อิสระ]] (7)<br /> {{colorbox|#808080}} [[ข้าราชการ]] (6)<br /> {{colorbox|#808080}} [[พรรคประชาธิปัตย์]] (1)<br /> {{colorbox|#808080}} [[แพทย์]] (1) | political_groups2 = | last_election1 = | next_election2 = | meeting_place = [[สัปปายะสภาสถาน]] [[เขตดุสิต]] [[กรุงเทพมหานคร]] [[ประเทศไทย]] | website = {{URL|https://discord.gg/ZeBQkrchEP}} }} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564|รัฐธรรมนูญ พ.ศ. 2564]] 009aaf40c04d3802115726c6e5f8498eec3577c9 148 144 2023-10-05T16:13:33Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ | name = สภานิติบัญญัติแห่งชาติ | coa_pic = | coa_res = | session_room = | session_res = | house_type = ระบบสภาเดียว | houses = | leader1_type = [[ประธานสภานิติบัญญัติแห่งชาติ|ประธาน]] | leader1 = [[เนติวิทย์ นวโชติ]] | party1 = | election1 = | leader2_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 1]] | leader2 = [[โฆษิต นวชาติ]] | party2 = | election2 = | leader3_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 2]] | leader3 = [[ณิชานันท์ ธนินทวรานนท์]] | party3 = | election3 = | members = 39 ที่นั่ง |structure1 = |structure1_res = 270px | house1 = | house2 = | political_groups1 = ได้รับการแต่งตั้งมาจากภาคส่วนต่าง ๆ<br />{{colorbox|#006400}} [[บริษัท วานิเฉียนกรุป จำกัด]] (10)<br /> {{colorbox|#964B00}} [[พรรคสมัยใหม่]] (8)<br /> {{colorbox|#FF0000}} [[นักการเมืองอิสระ|อิสระ]] (7)<br /> {{colorbox|#808080}} [[ข้าราชการ]] (6)<br /> {{colorbox|#808080}} [[พรรคประชาธิปัตย์]] (1)<br /> {{colorbox|#808080}} [[แพทย์]] (1) | political_groups2 = | last_election1 = | next_election2 = | meeting_place = [[สัปปายะสภาสถาน]] [[เขตดุสิต]] [[กรุงเทพมหานคร]] [[ประเทศไทย]] | website = {{URL|https://discord.gg/ZeBQkrchEP}} }} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564|รัฐธรรมนูญ พ.ศ. 2564]] == รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ == {| class="wikitable sortable" |- ! District ! Elected MP ! colspan=2 | Party ! Notes |- | Bangkok 1 | Paramet Wiriyarangsun | {{party name with color|Move Forward Party}} | |- | Bangkok 2 | Tisana Choonhavan | {{party name with color|Move Forward Party}} | |- |} 4bedb178e00ee37c1cb742748f139bf34fd595a1 149 148 2023-10-05T16:26:23Z PeachFullzZ 2 /* รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ */ wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ | name = สภานิติบัญญัติแห่งชาติ | coa_pic = | coa_res = | session_room = | session_res = | house_type = ระบบสภาเดียว | houses = | leader1_type = [[ประธานสภานิติบัญญัติแห่งชาติ|ประธาน]] | leader1 = [[เนติวิทย์ นวโชติ]] | party1 = | election1 = | leader2_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 1]] | leader2 = [[โฆษิต นวชาติ]] | party2 = | election2 = | leader3_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 2]] | leader3 = [[ณิชานันท์ ธนินทวรานนท์]] | party3 = | election3 = | members = 39 ที่นั่ง |structure1 = |structure1_res = 270px | house1 = | house2 = | political_groups1 = ได้รับการแต่งตั้งมาจากภาคส่วนต่าง ๆ<br />{{colorbox|#006400}} [[บริษัท วานิเฉียนกรุป จำกัด]] (10)<br /> {{colorbox|#964B00}} [[พรรคสมัยใหม่]] (8)<br /> {{colorbox|#FF0000}} [[นักการเมืองอิสระ|อิสระ]] (7)<br /> {{colorbox|#808080}} [[ข้าราชการ]] (6)<br /> {{colorbox|#808080}} [[พรรคประชาธิปัตย์]] (1)<br /> {{colorbox|#808080}} [[แพทย์]] (1) | political_groups2 = | last_election1 = | next_election2 = | meeting_place = [[สัปปายะสภาสถาน]] [[เขตดุสิต]] [[กรุงเทพมหานคร]] [[ประเทศไทย]] | website = {{URL|https://discord.gg/ZeBQkrchEP}} }} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564|รัฐธรรมนูญ พ.ศ. 2564]] == รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ == {| class="wikitable sortable" |- ! colspan=2 | กลุ่มรัฐสภา ! ชื่อ-นามสกุล ! อาชีพ ! หมายเหตุ |- | | กลุ่มแพทย์ | ขะเหมียว ธาราวัชรจินดา | ผู้อำนวยการ[[โรงพยาบาลจุฬาลงกรณ์ สภากาชาดไทย]] | |- | | กลุ่มอิสระ | คิเอะ เสาร์แก้ว | คอนเทนต์ครีเอเตอร์ | |- | | กลุ่มนักการเมือง | โฆษิต นวชาติ | อดีตประธานรัฐสภา และนักการเมือง | |- | | กลุ่มข้าราชการ | จรดล แซ่เหงียน | อธิบดี[[กรมศิลปากร]] | |- |} 541cfb106adef1101ae11bd58fcdb3995386c578 150 149 2023-10-05T16:28:41Z PeachFullzZ 2 /* รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ */ wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ | name = สภานิติบัญญัติแห่งชาติ | coa_pic = | coa_res = | session_room = | session_res = | house_type = ระบบสภาเดียว | houses = | leader1_type = [[ประธานสภานิติบัญญัติแห่งชาติ|ประธาน]] | leader1 = [[เนติวิทย์ นวโชติ]] | party1 = | election1 = | leader2_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 1]] | leader2 = [[โฆษิต นวชาติ]] | party2 = | election2 = | leader3_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 2]] | leader3 = [[ณิชานันท์ ธนินทวรานนท์]] | party3 = | election3 = | members = 39 ที่นั่ง |structure1 = |structure1_res = 270px | house1 = | house2 = | political_groups1 = ได้รับการแต่งตั้งมาจากภาคส่วนต่าง ๆ<br />{{colorbox|#006400}} [[บริษัท วานิเฉียนกรุป จำกัด]] (10)<br /> {{colorbox|#964B00}} [[พรรคสมัยใหม่]] (8)<br /> {{colorbox|#FF0000}} [[นักการเมืองอิสระ|อิสระ]] (7)<br /> {{colorbox|#808080}} [[ข้าราชการ]] (6)<br /> {{colorbox|#808080}} [[พรรคประชาธิปัตย์]] (1)<br /> {{colorbox|#808080}} [[แพทย์]] (1) | political_groups2 = | last_election1 = | next_election2 = | meeting_place = [[สัปปายะสภาสถาน]] [[เขตดุสิต]] [[กรุงเทพมหานคร]] [[ประเทศไทย]] | website = {{URL|https://discord.gg/ZeBQkrchEP}} }} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564|รัฐธรรมนูญ พ.ศ. 2564]] == รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ == {| class="wikitable sortable" |- ! colspan=2 | กลุ่มรัฐสภา ! ชื่อ-นามสกุล ! อาชีพ ! หมายเหตุ |- | | กลุ่มแพทย์ | ขะเหมียว ธาราวัชรจินดา | ผู้อำนวยการ[[โรงพยาบาลจุฬาลงกรณ์ สภากาชาดไทย]] | |- | | กลุ่มอิสระ | คิเอะ เสาร์แก้ว | คอนเทนต์ครีเอเตอร์ | |- | | กลุ่มนักการเมือง | โฆษิต นวชาติ | อดีตประธานรัฐสภา และนักการเมือง | รองประธานสภาคนที่ 1 |- | | กลุ่มข้าราชการ | จรดล แซ่เหงียน | อธิบดี[[กรมศิลปากร]] | |- | | กลุ่มนักการเมือง | อานุภาพ คุณูปจางบริรักษ์ | นายกรัฐมนตรี และหัวหน้า[[พรรคประชาธิปัตย์]] | |- |} a4bea6e471c17d3ca280c58cbe680cf57a7460d0 151 150 2023-10-05T16:31:09Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ | name = สภานิติบัญญัติแห่งชาติ | coa_pic = | coa_res = | session_room = | session_res = | house_type = ระบบสภาเดียว | houses = | leader1_type = [[ประธานสภานิติบัญญัติแห่งชาติ|ประธาน]] | leader1 = [[เนติวิทย์ นวโชติ]] | party1 = | election1 = | leader2_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 1]] | leader2 = [[โฆษิต นวชาติ]] | party2 = | election2 = | leader3_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 2]] | leader3 = [[ณิชานันท์ ธนินทวรานนท์]] | party3 = | election3 = | members = 39 ที่นั่ง |structure1 = |structure1_res = 270px | house1 = | house2 = | political_groups1 = ได้รับการแต่งตั้งมาจากภาคส่วนต่าง ๆ<br />{{colorbox|#006400}} [[บริษัท วานิเฉียนกรุป จำกัด]] (10)<br /> {{colorbox|#964B00}} [[พรรคสมัยใหม่]] (8)<br /> {{colorbox|#FF0000}} [[นักการเมืองอิสระ|อิสระ]] (7)<br /> {{colorbox|#808080}} [[ข้าราชการ]] (6)<br /> {{colorbox|#808080}} [[พรรคประชาธิปัตย์]] (1)<br /> {{colorbox|#808080}} [[แพทย์]] (1) | political_groups2 = | last_election1 = | next_election2 = | meeting_place = [[สัปปายะสภาสถาน]] [[เขตดุสิต]] [[กรุงเทพมหานคร]] [[ประเทศไทย]] | website = {{URL|https://discord.gg/ZeBQkrchEP}} }} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564]] == รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ == {| class="wikitable sortable" |- ! colspan=2 | กลุ่มรัฐสภา ! ชื่อ-นามสกุล ! อาชีพ ! หมายเหตุ |- | | กลุ่มแพทย์ | ขะเหมียว ธาราวัชรจินดา | ผู้อำนวยการ[[โรงพยาบาลจุฬาลงกรณ์ สภากาชาดไทย]] | |- | | กลุ่มอิสระ | คิเอะ เสาร์แก้ว | คอนเทนต์ครีเอเตอร์ | |- | | กลุ่มนักการเมือง | โฆษิต นวชาติ | อดีตประธานรัฐสภา และนักการเมือง | รองประธานสภาคนที่ 1 |- | | กลุ่มข้าราชการ | จรดล แซ่เหงียน | อธิบดี[[กรมศิลปากร]] | |- | | กลุ่มนักการเมือง | อานุภาพ คุณูปจางบริรักษ์ | นายกรัฐมนตรี และหัวหน้า[[พรรคประชาธิปัตย์]] | |- |} e907015a85618ddb378b7b7f23c68e3f209deb1b แม่แบบ:กล่องข้อมูล สภานิติบัญญัติ 10 69 127 2023-10-05T15:25:35Z PeachFullzZ 2 สร้างหน้าด้วย "{{Infobox | bodyclass = vcard | abovestyle = font-size: 125%; {{#if:{{{background_color|}}}|border-top: 2px solid {{{background_color}}}; border-bottom: 2px solid {{{background_color}}}|background-color: #ededed}} | above = <includeonly><div style="display:inline" class="fn org">{{{name}}}</div> {{#if:{{{native_name|}}}|<br /><div style="display:inline" class="nickname" {{#if:{{{native_name_lang|}}}|lang="{{{native_name_lang}}}"}}>{{{nati..." wikitext text/x-wiki {{Infobox | bodyclass = vcard | abovestyle = font-size: 125%; {{#if:{{{background_color|}}}|border-top: 2px solid {{{background_color}}}; border-bottom: 2px solid {{{background_color}}}|background-color: #ededed}} | above = <includeonly><div style="display:inline" class="fn org">{{{name}}}</div> {{#if:{{{native_name|}}}|<br /><div style="display:inline" class="nickname" {{#if:{{{native_name_lang|}}}|lang="{{{native_name_lang}}}"}}>{{{native_name}}}</div>{{#if:{{{transcription_name|}}}|<br /><div style="display:inline" class="nickname">{{{transcription_name}}}</div>}}}}</includeonly> | subheader = {{{legislature|}}} | image = {{#invoke:InfoboxImage|InfoboxImage |image={{{coa_pic|{{{coa-pic|}}}}}} |size={{{coa_res|{{{coa-res|}}}}}} |sizedefault=frameless |upright=yes |alt={{{coa_alt|{{{coa-alt|Coat of arms or logo}}}}}} }} | caption = {{{coa_caption|}}} | image2 = {{#invoke:InfoboxImage |InfoboxImage |image={{{logo|{{{logo_pic|{{{logo-pic|}}}}}}}}} |size={{{logo_res|{{{logo-res|}}}}}} |sizedefault=frameless |upright=yes |alt={{{logo_alt|{{{logo-alt|Logo}}}}}} }} | caption2 = {{{logo_caption|}}} | headerstyle = {{#if:{{{background_color|}}}|border-top: 2px solid {{{background_color}}}; border-bottom: 2px solid {{{background_color}}}|background-color: #ededed}} | labelstyle = {{{labelstyle|}}} | header1 = {{#if:{{{house_type|}}}{{{houses|}}}{{{term_limits|}}}|Type}} | label2 = Type | data2 = {{#if:{{{house_type|}}} |<div style="padding:0.1em 0;line-height:1.3em;<!--(modified longitem)-->"><div style="display:inline" class="category">{{#ifexist:{{{house_type}}}|[[{{{house_type}}}]]|{{{house_type}}}}}</div> {{#if:{{{body|}}} |of the [[{{{body}}}]]}} {{#if:{{{jurisdiction|}}} |of [[{{{jurisdiction}}}]]}}</div>}} | label3 = {{#if:{{{houses|}}}|Houses|Chambers}} | data3 = {{#if:{{{houses|}}}|{{{houses}}}|{{{chambers|}}}}} | label4 = {{#if:{{{pres-in-parl|}}}{{{crown-in-parl|}}}|[[King-in-Parliament|Sovereign]]|}} | data4 = {{#if:{{{pres-in-parl|}}}|{{{pres-in-parl}}}|{{{crown-in-parl|}}}}} | label5 = {{longitem|Term limits}} | data5 = {{{term_limits|}}} | header6 = {{#if:{{{foundation|}}}{{{disbanded|}}}{{{preceded_by|}}}{{{succeeded_by|}}}{{{new_session|}}}|History}} | label7 = {{#if:{{{foundation|}}}|Founded|Established}} | data7 = {{#if:{{{foundation|}}}|{{{foundation}}}|{{{established|}}}}} | label8 = Disbanded | data8 = {{{disbanded|}}} | label9 = Preceded&nbsp;by | data9 = {{{preceded_by|}}} | label10 = Succeeded&nbsp;by | data10 = {{{succeeded_by|}}} | label11 = {{longitem|New session started}} | data11 = {{{new_session|}}} | header14 = {{#if:{{{leader1|}}}{{{leader2|}}}{{{leader3|}}}{{{leader4|}}}{{{leader5|}}}{{{leader6|}}}{{{leader7|}}}{{{leader8|}}}|Leadership}} | label15 = {{longitem|{{{leader1_type|}}}}} | data15 = {{#if:{{{leader1|}}} |{{longitem|style=line-height:1.3em|{{{leader1|}}}{{#if:{{{party1|}}}|{{#ifeq:{{Str index|{{{party1|}}}|1}}|(||,}}&#32;{{{party1|}}}}} {{#if:{{{election1|}}}|<br/>since {{{election1|}}}|{{#if:{{{leader1_term|}}}|<br/>{{{leader1_term}}}}} }} }} }} | label16 = {{longitem|style=line-height:1.3em|{{{leader2_type|}}}}} | data16 = {{#if:{{{leader2|}}} |{{longitem|style=line-height:1.3em|{{{leader2|}}}{{#if:{{{party2|}}}|{{#ifeq:{{Str index|{{{party2|}}}|1}}|(||,}}&#32;{{{party2|}}}}} {{#if:{{{election2|}}}|<br/>since {{{election2|}}}|{{#if:{{{leader2_term|}}}|<br/>{{{leader2_term}}}}} }} }} }} | label17 = {{longitem|style=line-height:1.3em|{{{leader3_type|}}}}} | data17 = {{#if:{{{leader3|}}} |{{longitem|style=line-height:1.3em|{{{leader3|}}}{{#if:{{{party3|}}}|{{#ifeq:{{Str index|{{{party3|}}}|1}}|(||,}}&#32;{{{party3|}}}}} {{#if:{{{election3|}}}|<br/>since {{{election3|}}}|{{#if:{{{leader3_term|}}}|<br/>{{{leader3_term}}}}} }} }} }} | label18 = {{longitem|style=line-height:1.3em|{{{leader4_type|}}}}} | data18 = {{#if:{{{leader4|}}} |{{longitem|style=line-height:1.3em|{{{leader4|}}}{{#if:{{{party4|}}}|{{#ifeq:{{Str index|{{{party4|}}}|1}}|(||,}}&#32;{{{party4|}}}}} {{#if:{{{election4|}}}|<br/>since {{{election4|}}}|{{#if:{{{leader4_term|}}}|<br/>{{{leader4_term}}}}} }} }} }} | label19 = {{longitem|style=line-height:1.3em|{{{leader5_type|}}}}} | data19 = {{#if:{{{leader5|}}} |{{longitem|style=line-height:1.3em|{{{leader5|}}}{{#if:{{{party5|}}}|{{#ifeq:{{Str index|{{{party5|}}}|1}}|(||,}}&#32;{{{party5|}}}}} {{#if:{{{election5|}}}|<br/>since {{{election5|}}}|{{#if:{{{leader5_term|}}}|<br/>{{{leader5_term}}}}} }} }} }} | label20 = {{longitem|style=line-height:1.3em|{{{leader6_type|}}}}} | data20 = {{#if:{{{leader6|}}} |{{longitem|style=line-height:1.3em|{{{leader6|}}}{{#if:{{{party6|}}}|{{#ifeq:{{Str index|{{{party6|}}}|1}}|(||,}}&#32;{{{party6|}}}}} {{#if:{{{election6|}}}|<br/>since {{{election6|}}}|{{#if:{{{leader6_term|}}}|<br/>{{{leader6_term}}}}} }} }} }} | label21 = {{longitem|style=line-height:1.3em|{{{leader7_type|}}}}} | data21 = {{#if:{{{leader7|}}} |{{longitem|style=line-height:1.3em|{{{leader7|}}}{{#if:{{{party7|}}}|{{#ifeq:{{Str index|{{{party7|}}}|1}}|(||,}}&#32;{{{party7|}}}}} {{#if:{{{election7|}}}|<br/>since {{{election7|}}}|{{#if:{{{leader7_term|}}}|<br/>{{{leader7_term}}}}} }} }} }} | label22 = {{longitem|style=line-height:1.3em|{{{leader8_type|}}}}} | data22 = {{#if:{{{leader8|}}} |{{longitem|style=line-height:1.3em|{{{leader8|}}}{{#if:{{{party8|}}}|{{#ifeq:{{Str index|{{{party8|}}}|1}}|(||,}}&#32;{{{party8|}}}}} {{#if:{{{election8|}}}|<br/>since {{{election8|}}}|{{#if:{{{leader8_term|}}}|<br/>{{{leader8_term}}}}} }} }} }} | label23 = {{longitem|style=line-height:1.3em|{{{leader9_type|}}}}} | data23 = {{#if:{{{leader9|}}} |{{longitem|style=line-height:1.3em|{{{leader9|}}}{{#if:{{{party9|}}}|{{#ifeq:{{Str index|{{{party9|}}}|1}}|(||,}}&#32;{{{party9|}}}}} {{#if:{{{election9|}}}|<br/>since {{{election9|}}}|{{#if:{{{leader9_term|}}}|<br/>{{{leader9_term}}}}} }} }} }} | label24 = {{longitem|style=line-height:1.3em|{{{leader10_type|}}}}} | data24 = {{#if:{{{leader10|}}} |{{longitem|style=line-height:1.3em|{{{leader10|}}}{{#if:{{{party10|}}}|{{#ifeq:{{Str index|{{{party10|}}}|1}}|(||,}}&#32;{{{party10|}}}}} {{#if:{{{election10|}}}|<br/>since {{{election10|}}}|{{#if:{{{leader10_term|}}}|<br/>{{{leader10_term}}}}} }} }} }} | header25 = {{#if:{{{structure1|}}}{{{political_groups1|}}}{{{structure2|}}}{{{political_groups2|}}}{{{committees1|}}}{{{committees2|}}}{{{joint_committees|}}}{{{term_length|}}}{{{authority|}}}{{{salary|}}} {{{seats1|}}}{{{seats2|}}}{{{seats3|}}}{{{seats4|}}}{{{seats5|}}}{{{seats6|}}}{{{seats7|}}}{{{seats8|}}}|Structure}} | label26 = Seats | data26 = {{#if:{{{members|}}}|{{{members}}}|{{{seats|}}}}} | data27 = {{#invoke:InfoboxImage|InfoboxImage|image={{{structure1|}}}|size={{{structure1_res|}}}|sizedefault=120px|alt={{{structure1_alt|}}}}} | label28 = {{longitem|{{#if:{{{house1|}}}|{{{house1}}} political groups|Political groups}}}} | data28 = {{{political_groups1|}}} | data29 = {{#invoke:InfoboxImage|InfoboxImage|image={{{structure2|}}}|size={{{structure2_res|}}}|sizedefault=120px|alt={{{structure2_alt|}}}}} | label30 = {{longitem|{{#if:{{{house2|}}}|{{{house2}}} political groups|Political groups}}}} | data30 = {{{political_groups2|}}} | label31 = {{#if:{{{house1|}}}|{{{house1}}} committees|Committees}} | data31 = {{{committees1|}}} | label32 = {{#if:{{{house2|}}}|{{{house2}}} committees|Committees}} | data32 = {{{committees2|}}} | label33 = {{longitem|Joint committees}} | data33 = {{{joint_committees|}}} | label34 = {{longitem|Length of term}} | data34 = {{{term_length|}}} | label35 = Authority | data35 = {{{authority|}}} | label36 = Salary | data36 = {{{salary|}}} | label37 = {{longitem|{{{seats1_title|}}}}} | data37 = {{{seats1|}}} | label38 = {{longitem|{{{seats2_title|}}}}} | data38 = {{{seats2|}}} | label39 = {{longitem|{{{seats3_title|}}}}} | data39 = {{{seats3|}}} | label40 = {{longitem|{{{seats4_title|}}}}} | data40 = {{{seats4|}}} | label41 = {{longitem|{{{seats5_title|}}}}} | data41 = {{{seats5|}}} | label42 = {{longitem|{{{seats6_title|}}}}} | data42 = {{{seats6|}}} | label43 = {{longitem|{{{seats7_title|}}}}} | data43 = {{{seats7|}}} | label44 = {{longitem|{{{seats8_title|}}}}} | data44 = {{{seats8|}}} | label45 = {{longitem|{{{seats9_title|}}}}} | data45 = {{{seats9|}}} | label46 = {{longitem|{{{seats10_title|}}}}} | data46 = {{{seats10|}}} | header47 = {{#if:{{{voting_system1|}}}{{{voting_system2|}}}{{{first_election1|}}}{{{first_election2|}}}{{{first_election3|}}}{{{last_election1|}}}{{{last_election2|}}}{{{last_election3|}}}{{{next_election1|}}}{{{next_election2|}}}{{{next_election3|}}}{{{redistricting|}}}|Elections}} | label48 = {{longitem|{{#if:{{{house1|}}}|{{{house1}}} [[electoral system|voting system]]|[[electoral system|Voting system]]}}}} | data48 = {{{voting_system1|}}} | label49 = {{longitem|{{#if:{{{house2|}}}|{{{house2}}} [[electoral system|voting system]]|[[electoral system|Voting system]]}}}} | data49 = {{{voting_system2|}}} | label50 = {{longitem|{{#if:{{{house1|}}}|First {{{house1}}} election|First election}}}} | data50 = {{{first_election1|}}} | label51 = {{longitem|{{#if:{{{house2|}}}|First {{{house2}}} election|First election}}}} | data51 = {{{first_election2|}}} | label52 = {{longitem|First general election}} | data52 = {{{first_election3|}}} | label53 = {{longitem|{{#if:{{{house1|}}}|Last {{{house1}}} election|Last election}}}} | data53 = {{{last_election1|}}} | label54 = {{longitem|{{#if:{{{house2|}}}|Last {{{house2}}} election|Last election}}}} | data54 = {{{last_election2|}}} | label55 = {{longitem|Last general election}} | data55 = {{{last_election3|}}} | label56 = {{longitem|{{#if:{{{house1|}}}|Next {{{house1}}} election|Next election}}}} | data56 = {{{next_election1|}}} | label57 = {{longitem|{{#if:{{{house2|}}}|Next {{{house2}}} election|Next election}}}} | data57 = {{{next_election2|}}} | label58 = {{longitem|Next general election}} | data58 = {{{next_election3|}}} | label59 = Redistricting | data59 = {{{redistricting|}}} | header60 = {{#if:{{{motto|}}}|Motto}} | data61 = {{{motto|}}} | header62 = {{#if:{{{session_room|}}}{{{meeting_place|}}}|Meeting place}} | data63 = {{#invoke:InfoboxImage|InfoboxImage|image={{{session_room|}}}|size={{{session_res|}}}|alt={{{session_alt|}}}}} | data64 = {{{meeting_place|}}} | class64 = label | data65 = {{#invoke:InfoboxImage|InfoboxImage|image={{{session_room2|}}}|size={{{session_res2|}}}|alt={{{session_alt2|}}}}} | data66 = {{{meeting_place2|}}} | class66 = label | data67 = {{#invoke:InfoboxImage|InfoboxImage|image={{{session_room3|}}}|size={{{session_res3|}}}|alt={{{session_alt3|}}}}} | data68 = {{{meeting_place3|}}} | class68 = label | header69 = {{#if:{{{website|}}}|Website}} | data70 = {{{website|}}} | header71 = {{#if:{{{constitution|}}}|Constitution}} | data72 = {{{constitution|}}} | header73 = {{#if:{{{rules|}}}|Rules}} | data74 = {{{rules|}}} | header75 = {{#if:{{{footnotes|}}}|Footnotes}} | data76 = {{{footnotes|}}} }}{{Main other|{{#if:{{{background_color|}}}{{{text_color|}}}|[[Category:Infobox legislature with background color]]}}}}{{#invoke:Check for unknown parameters|check|unknown={{main other|}}|preview=Page using [[Template:Infobox legislature]] with unknown parameter "_VALUE_"|ignoreblank=y| authority | background_color | body | categories | chambers | coa_alt | coa_caption | coa_pic | coa_res | coa-alt | coa-pic | coa-res | committees1 | committees2 | constitution | demo | disbanded | election1 | election2 | election3 | election4 | election5 | election6 | election7 | election8 | election9 | election10 | established | first_election1 | first_election2 | first_election3 | footnotes | foundation | house_type | house1 | house2 | houses | joint_committees | jurisdiction | labelstyle | last_election1 | last_election2 | last_election3 | leader1 | leader1_type | leader2 | leader2_type | leader3 | leader3_type | leader4 | leader4_type | leader5 | leader5_type | leader6 | leader6_type | leader7 | leader7_type | leader8 | leader8_type | leader9 | leader9_type | leader10 | leader10_type | legislature | logo | logo_alt | logo_caption | logo_pic | logo_res | logo-alt | logo-pic | logo-res | meeting_place | meeting_place2 | meeting_place3 | members | motto | name | native_name | native_name_lang | new_session | next_election1 | next_election2 | next_election3 | nocat | party1 | party2 | party3 | party4 | party5 | party6 | party7 | party8 | party9 | party10 | political_groups1 | political_groups2 | preceded_by | redistricting | rules | salary | seats | seats1 | seats1_title | seats2 | seats2_title | seats3 | seats3_title | seats4 | seats4_title | seats5 | seats5_title | seats6 | seats6_title | seats7 | seats7_title | seats8 | seats8_title | session_alt | session_alt2 | session_alt3 | session_res | session_res2 | session_res3 | session_room | session_room2 | session_room3 | structure1 | structure1_alt | structure1_res | structure2 | structure2_alt | structure2_res | succeeded_by | term_length | term_limits | text_color | transcription_name | voting_system1 | voting_system2 | website }}<noinclude> {{documentation}}<!--Please add this template's categories to the /doc subpage, not here - thanks!--> </noinclude> d1dcf08808e3e00d4e8943feee4e04c44a237f90 128 127 2023-10-05T15:26:14Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:กล่องข้อมูล สภานิติบัญญัติ]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki {{Infobox | bodyclass = vcard | abovestyle = font-size: 125%; {{#if:{{{background_color|}}}|border-top: 2px solid {{{background_color}}}; border-bottom: 2px solid {{{background_color}}}|background-color: #ededed}} | above = <includeonly><div style="display:inline" class="fn org">{{{name}}}</div> {{#if:{{{native_name|}}}|<br /><div style="display:inline" class="nickname" {{#if:{{{native_name_lang|}}}|lang="{{{native_name_lang}}}"}}>{{{native_name}}}</div>{{#if:{{{transcription_name|}}}|<br /><div style="display:inline" class="nickname">{{{transcription_name}}}</div>}}}}</includeonly> | subheader = {{{legislature|}}} | image = {{#invoke:InfoboxImage|InfoboxImage |image={{{coa_pic|{{{coa-pic|}}}}}} |size={{{coa_res|{{{coa-res|}}}}}} |sizedefault=frameless |upright=yes |alt={{{coa_alt|{{{coa-alt|Coat of arms or logo}}}}}} }} | caption = {{{coa_caption|}}} | image2 = {{#invoke:InfoboxImage |InfoboxImage |image={{{logo|{{{logo_pic|{{{logo-pic|}}}}}}}}} |size={{{logo_res|{{{logo-res|}}}}}} |sizedefault=frameless |upright=yes |alt={{{logo_alt|{{{logo-alt|Logo}}}}}} }} | caption2 = {{{logo_caption|}}} | headerstyle = {{#if:{{{background_color|}}}|border-top: 2px solid {{{background_color}}}; border-bottom: 2px solid {{{background_color}}}|background-color: #ededed}} | labelstyle = {{{labelstyle|}}} | header1 = {{#if:{{{house_type|}}}{{{houses|}}}{{{term_limits|}}}|Type}} | label2 = Type | data2 = {{#if:{{{house_type|}}} |<div style="padding:0.1em 0;line-height:1.3em;<!--(modified longitem)-->"><div style="display:inline" class="category">{{#ifexist:{{{house_type}}}|[[{{{house_type}}}]]|{{{house_type}}}}}</div> {{#if:{{{body|}}} |of the [[{{{body}}}]]}} {{#if:{{{jurisdiction|}}} |of [[{{{jurisdiction}}}]]}}</div>}} | label3 = {{#if:{{{houses|}}}|Houses|Chambers}} | data3 = {{#if:{{{houses|}}}|{{{houses}}}|{{{chambers|}}}}} | label4 = {{#if:{{{pres-in-parl|}}}{{{crown-in-parl|}}}|[[King-in-Parliament|Sovereign]]|}} | data4 = {{#if:{{{pres-in-parl|}}}|{{{pres-in-parl}}}|{{{crown-in-parl|}}}}} | label5 = {{longitem|Term limits}} | data5 = {{{term_limits|}}} | header6 = {{#if:{{{foundation|}}}{{{disbanded|}}}{{{preceded_by|}}}{{{succeeded_by|}}}{{{new_session|}}}|History}} | label7 = {{#if:{{{foundation|}}}|Founded|Established}} | data7 = {{#if:{{{foundation|}}}|{{{foundation}}}|{{{established|}}}}} | label8 = Disbanded | data8 = {{{disbanded|}}} | label9 = Preceded&nbsp;by | data9 = {{{preceded_by|}}} | label10 = Succeeded&nbsp;by | data10 = {{{succeeded_by|}}} | label11 = {{longitem|New session started}} | data11 = {{{new_session|}}} | header14 = {{#if:{{{leader1|}}}{{{leader2|}}}{{{leader3|}}}{{{leader4|}}}{{{leader5|}}}{{{leader6|}}}{{{leader7|}}}{{{leader8|}}}|Leadership}} | label15 = {{longitem|{{{leader1_type|}}}}} | data15 = {{#if:{{{leader1|}}} |{{longitem|style=line-height:1.3em|{{{leader1|}}}{{#if:{{{party1|}}}|{{#ifeq:{{Str index|{{{party1|}}}|1}}|(||,}}&#32;{{{party1|}}}}} {{#if:{{{election1|}}}|<br/>since {{{election1|}}}|{{#if:{{{leader1_term|}}}|<br/>{{{leader1_term}}}}} }} }} }} | label16 = {{longitem|style=line-height:1.3em|{{{leader2_type|}}}}} | data16 = {{#if:{{{leader2|}}} |{{longitem|style=line-height:1.3em|{{{leader2|}}}{{#if:{{{party2|}}}|{{#ifeq:{{Str index|{{{party2|}}}|1}}|(||,}}&#32;{{{party2|}}}}} {{#if:{{{election2|}}}|<br/>since {{{election2|}}}|{{#if:{{{leader2_term|}}}|<br/>{{{leader2_term}}}}} }} }} }} | label17 = {{longitem|style=line-height:1.3em|{{{leader3_type|}}}}} | data17 = {{#if:{{{leader3|}}} |{{longitem|style=line-height:1.3em|{{{leader3|}}}{{#if:{{{party3|}}}|{{#ifeq:{{Str index|{{{party3|}}}|1}}|(||,}}&#32;{{{party3|}}}}} {{#if:{{{election3|}}}|<br/>since {{{election3|}}}|{{#if:{{{leader3_term|}}}|<br/>{{{leader3_term}}}}} }} }} }} | label18 = {{longitem|style=line-height:1.3em|{{{leader4_type|}}}}} | data18 = {{#if:{{{leader4|}}} |{{longitem|style=line-height:1.3em|{{{leader4|}}}{{#if:{{{party4|}}}|{{#ifeq:{{Str index|{{{party4|}}}|1}}|(||,}}&#32;{{{party4|}}}}} {{#if:{{{election4|}}}|<br/>since {{{election4|}}}|{{#if:{{{leader4_term|}}}|<br/>{{{leader4_term}}}}} }} }} }} | label19 = {{longitem|style=line-height:1.3em|{{{leader5_type|}}}}} | data19 = {{#if:{{{leader5|}}} |{{longitem|style=line-height:1.3em|{{{leader5|}}}{{#if:{{{party5|}}}|{{#ifeq:{{Str index|{{{party5|}}}|1}}|(||,}}&#32;{{{party5|}}}}} {{#if:{{{election5|}}}|<br/>since {{{election5|}}}|{{#if:{{{leader5_term|}}}|<br/>{{{leader5_term}}}}} }} }} }} | label20 = {{longitem|style=line-height:1.3em|{{{leader6_type|}}}}} | data20 = {{#if:{{{leader6|}}} |{{longitem|style=line-height:1.3em|{{{leader6|}}}{{#if:{{{party6|}}}|{{#ifeq:{{Str index|{{{party6|}}}|1}}|(||,}}&#32;{{{party6|}}}}} {{#if:{{{election6|}}}|<br/>since {{{election6|}}}|{{#if:{{{leader6_term|}}}|<br/>{{{leader6_term}}}}} }} }} }} | label21 = {{longitem|style=line-height:1.3em|{{{leader7_type|}}}}} | data21 = {{#if:{{{leader7|}}} |{{longitem|style=line-height:1.3em|{{{leader7|}}}{{#if:{{{party7|}}}|{{#ifeq:{{Str index|{{{party7|}}}|1}}|(||,}}&#32;{{{party7|}}}}} {{#if:{{{election7|}}}|<br/>since {{{election7|}}}|{{#if:{{{leader7_term|}}}|<br/>{{{leader7_term}}}}} }} }} }} | label22 = {{longitem|style=line-height:1.3em|{{{leader8_type|}}}}} | data22 = {{#if:{{{leader8|}}} |{{longitem|style=line-height:1.3em|{{{leader8|}}}{{#if:{{{party8|}}}|{{#ifeq:{{Str index|{{{party8|}}}|1}}|(||,}}&#32;{{{party8|}}}}} {{#if:{{{election8|}}}|<br/>since {{{election8|}}}|{{#if:{{{leader8_term|}}}|<br/>{{{leader8_term}}}}} }} }} }} | label23 = {{longitem|style=line-height:1.3em|{{{leader9_type|}}}}} | data23 = {{#if:{{{leader9|}}} |{{longitem|style=line-height:1.3em|{{{leader9|}}}{{#if:{{{party9|}}}|{{#ifeq:{{Str index|{{{party9|}}}|1}}|(||,}}&#32;{{{party9|}}}}} {{#if:{{{election9|}}}|<br/>since {{{election9|}}}|{{#if:{{{leader9_term|}}}|<br/>{{{leader9_term}}}}} }} }} }} | label24 = {{longitem|style=line-height:1.3em|{{{leader10_type|}}}}} | data24 = {{#if:{{{leader10|}}} |{{longitem|style=line-height:1.3em|{{{leader10|}}}{{#if:{{{party10|}}}|{{#ifeq:{{Str index|{{{party10|}}}|1}}|(||,}}&#32;{{{party10|}}}}} {{#if:{{{election10|}}}|<br/>since {{{election10|}}}|{{#if:{{{leader10_term|}}}|<br/>{{{leader10_term}}}}} }} }} }} | header25 = {{#if:{{{structure1|}}}{{{political_groups1|}}}{{{structure2|}}}{{{political_groups2|}}}{{{committees1|}}}{{{committees2|}}}{{{joint_committees|}}}{{{term_length|}}}{{{authority|}}}{{{salary|}}} {{{seats1|}}}{{{seats2|}}}{{{seats3|}}}{{{seats4|}}}{{{seats5|}}}{{{seats6|}}}{{{seats7|}}}{{{seats8|}}}|Structure}} | label26 = Seats | data26 = {{#if:{{{members|}}}|{{{members}}}|{{{seats|}}}}} | data27 = {{#invoke:InfoboxImage|InfoboxImage|image={{{structure1|}}}|size={{{structure1_res|}}}|sizedefault=120px|alt={{{structure1_alt|}}}}} | label28 = {{longitem|{{#if:{{{house1|}}}|{{{house1}}} political groups|Political groups}}}} | data28 = {{{political_groups1|}}} | data29 = {{#invoke:InfoboxImage|InfoboxImage|image={{{structure2|}}}|size={{{structure2_res|}}}|sizedefault=120px|alt={{{structure2_alt|}}}}} | label30 = {{longitem|{{#if:{{{house2|}}}|{{{house2}}} political groups|Political groups}}}} | data30 = {{{political_groups2|}}} | label31 = {{#if:{{{house1|}}}|{{{house1}}} committees|Committees}} | data31 = {{{committees1|}}} | label32 = {{#if:{{{house2|}}}|{{{house2}}} committees|Committees}} | data32 = {{{committees2|}}} | label33 = {{longitem|Joint committees}} | data33 = {{{joint_committees|}}} | label34 = {{longitem|Length of term}} | data34 = {{{term_length|}}} | label35 = Authority | data35 = {{{authority|}}} | label36 = Salary | data36 = {{{salary|}}} | label37 = {{longitem|{{{seats1_title|}}}}} | data37 = {{{seats1|}}} | label38 = {{longitem|{{{seats2_title|}}}}} | data38 = {{{seats2|}}} | label39 = {{longitem|{{{seats3_title|}}}}} | data39 = {{{seats3|}}} | label40 = {{longitem|{{{seats4_title|}}}}} | data40 = {{{seats4|}}} | label41 = {{longitem|{{{seats5_title|}}}}} | data41 = {{{seats5|}}} | label42 = {{longitem|{{{seats6_title|}}}}} | data42 = {{{seats6|}}} | label43 = {{longitem|{{{seats7_title|}}}}} | data43 = {{{seats7|}}} | label44 = {{longitem|{{{seats8_title|}}}}} | data44 = {{{seats8|}}} | label45 = {{longitem|{{{seats9_title|}}}}} | data45 = {{{seats9|}}} | label46 = {{longitem|{{{seats10_title|}}}}} | data46 = {{{seats10|}}} | header47 = {{#if:{{{voting_system1|}}}{{{voting_system2|}}}{{{first_election1|}}}{{{first_election2|}}}{{{first_election3|}}}{{{last_election1|}}}{{{last_election2|}}}{{{last_election3|}}}{{{next_election1|}}}{{{next_election2|}}}{{{next_election3|}}}{{{redistricting|}}}|Elections}} | label48 = {{longitem|{{#if:{{{house1|}}}|{{{house1}}} [[electoral system|voting system]]|[[electoral system|Voting system]]}}}} | data48 = {{{voting_system1|}}} | label49 = {{longitem|{{#if:{{{house2|}}}|{{{house2}}} [[electoral system|voting system]]|[[electoral system|Voting system]]}}}} | data49 = {{{voting_system2|}}} | label50 = {{longitem|{{#if:{{{house1|}}}|First {{{house1}}} election|First election}}}} | data50 = {{{first_election1|}}} | label51 = {{longitem|{{#if:{{{house2|}}}|First {{{house2}}} election|First election}}}} | data51 = {{{first_election2|}}} | label52 = {{longitem|First general election}} | data52 = {{{first_election3|}}} | label53 = {{longitem|{{#if:{{{house1|}}}|Last {{{house1}}} election|Last election}}}} | data53 = {{{last_election1|}}} | label54 = {{longitem|{{#if:{{{house2|}}}|Last {{{house2}}} election|Last election}}}} | data54 = {{{last_election2|}}} | label55 = {{longitem|Last general election}} | data55 = {{{last_election3|}}} | label56 = {{longitem|{{#if:{{{house1|}}}|Next {{{house1}}} election|Next election}}}} | data56 = {{{next_election1|}}} | label57 = {{longitem|{{#if:{{{house2|}}}|Next {{{house2}}} election|Next election}}}} | data57 = {{{next_election2|}}} | label58 = {{longitem|Next general election}} | data58 = {{{next_election3|}}} | label59 = Redistricting | data59 = {{{redistricting|}}} | header60 = {{#if:{{{motto|}}}|Motto}} | data61 = {{{motto|}}} | header62 = {{#if:{{{session_room|}}}{{{meeting_place|}}}|Meeting place}} | data63 = {{#invoke:InfoboxImage|InfoboxImage|image={{{session_room|}}}|size={{{session_res|}}}|alt={{{session_alt|}}}}} | data64 = {{{meeting_place|}}} | class64 = label | data65 = {{#invoke:InfoboxImage|InfoboxImage|image={{{session_room2|}}}|size={{{session_res2|}}}|alt={{{session_alt2|}}}}} | data66 = {{{meeting_place2|}}} | class66 = label | data67 = {{#invoke:InfoboxImage|InfoboxImage|image={{{session_room3|}}}|size={{{session_res3|}}}|alt={{{session_alt3|}}}}} | data68 = {{{meeting_place3|}}} | class68 = label | header69 = {{#if:{{{website|}}}|Website}} | data70 = {{{website|}}} | header71 = {{#if:{{{constitution|}}}|Constitution}} | data72 = {{{constitution|}}} | header73 = {{#if:{{{rules|}}}|Rules}} | data74 = {{{rules|}}} | header75 = {{#if:{{{footnotes|}}}|Footnotes}} | data76 = {{{footnotes|}}} }}{{Main other|{{#if:{{{background_color|}}}{{{text_color|}}}|[[Category:Infobox legislature with background color]]}}}}{{#invoke:Check for unknown parameters|check|unknown={{main other|}}|preview=Page using [[Template:Infobox legislature]] with unknown parameter "_VALUE_"|ignoreblank=y| authority | background_color | body | categories | chambers | coa_alt | coa_caption | coa_pic | coa_res | coa-alt | coa-pic | coa-res | committees1 | committees2 | constitution | demo | disbanded | election1 | election2 | election3 | election4 | election5 | election6 | election7 | election8 | election9 | election10 | established | first_election1 | first_election2 | first_election3 | footnotes | foundation | house_type | house1 | house2 | houses | joint_committees | jurisdiction | labelstyle | last_election1 | last_election2 | last_election3 | leader1 | leader1_type | leader2 | leader2_type | leader3 | leader3_type | leader4 | leader4_type | leader5 | leader5_type | leader6 | leader6_type | leader7 | leader7_type | leader8 | leader8_type | leader9 | leader9_type | leader10 | leader10_type | legislature | logo | logo_alt | logo_caption | logo_pic | logo_res | logo-alt | logo-pic | logo-res | meeting_place | meeting_place2 | meeting_place3 | members | motto | name | native_name | native_name_lang | new_session | next_election1 | next_election2 | next_election3 | nocat | party1 | party2 | party3 | party4 | party5 | party6 | party7 | party8 | party9 | party10 | political_groups1 | political_groups2 | preceded_by | redistricting | rules | salary | seats | seats1 | seats1_title | seats2 | seats2_title | seats3 | seats3_title | seats4 | seats4_title | seats5 | seats5_title | seats6 | seats6_title | seats7 | seats7_title | seats8 | seats8_title | session_alt | session_alt2 | session_alt3 | session_res | session_res2 | session_res3 | session_room | session_room2 | session_room3 | structure1 | structure1_alt | structure1_res | structure2 | structure2_alt | structure2_res | succeeded_by | term_length | term_limits | text_color | transcription_name | voting_system1 | voting_system2 | website }}<noinclude> {{documentation}}<!--Please add this template's categories to the /doc subpage, not here - thanks!--> </noinclude> d1dcf08808e3e00d4e8943feee4e04c44a237f90 147 128 2023-10-05T16:08:46Z PeachFullzZ 2 wikitext text/x-wiki {{Infobox | bodyclass = vcard | abovestyle = font-size: 125%; {{#if:{{{background_color|}}}|border-top: 2px solid {{{background_color}}}; border-bottom: 2px solid {{{background_color}}}|background-color: #ededed}} | above = <includeonly><div style="display:inline" class="fn org">{{{name}}}</div> {{#if:{{{native_name|}}}|<br /><div style="display:inline" class="nickname" {{#if:{{{native_name_lang|}}}|lang="{{{native_name_lang}}}"}}>{{{native_name}}}</div>{{#if:{{{transcription_name|}}}|<br /><div style="display:inline" class="nickname">{{{transcription_name}}}</div>}}}}</includeonly> | subheader = {{{legislature|}}} | image = {{#invoke:InfoboxImage|InfoboxImage |image={{{coa_pic|{{{coa-pic|}}}}}} |size={{{coa_res|{{{coa-res|}}}}}} |sizedefault=frameless |upright=yes |alt={{{coa_alt|{{{coa-alt|Coat of arms or logo}}}}}} }} | caption = {{{coa_caption|}}} | image2 = {{#invoke:InfoboxImage |InfoboxImage |image={{{logo|{{{logo_pic|{{{logo-pic|}}}}}}}}} |size={{{logo_res|{{{logo-res|}}}}}} |sizedefault=frameless |upright=yes |alt={{{logo_alt|{{{logo-alt|Logo}}}}}} }} | caption2 = {{{logo_caption|}}} | headerstyle = {{#if:{{{background_color|}}}|border-top: 2px solid {{{background_color}}}; border-bottom: 2px solid {{{background_color}}}|background-color: #ededed}} | labelstyle = {{{labelstyle|}}} | header1 = {{#if:{{{house_type|}}}{{{houses|}}}{{{term_limits|}}}|ประเภท}} | label2 = ประเภท | data2 = {{#if:{{{house_type|}}} |<div style="padding:0.1em 0;line-height:1.3em;<!--(modified longitem)-->"><div style="display:inline" class="category">{{#ifexist:{{{house_type}}}|[[{{{house_type}}}]]|{{{house_type}}}}}</div> {{#if:{{{body|}}} |of the [[{{{body}}}]]}} {{#if:{{{jurisdiction|}}} |of [[{{{jurisdiction}}}]]}}</div>}} | label3 = {{#if:{{{houses|}}}|Houses|Chambers}} | data3 = {{#if:{{{houses|}}}|{{{houses}}}|{{{chambers|}}}}} | label4 = {{#if:{{{pres-in-parl|}}}{{{crown-in-parl|}}}|[[King-in-Parliament|Sovereign]]|}} | data4 = {{#if:{{{pres-in-parl|}}}|{{{pres-in-parl}}}|{{{crown-in-parl|}}}}} | label5 = {{longitem|Term limits}} | data5 = {{{term_limits|}}} | header6 = {{#if:{{{foundation|}}}{{{disbanded|}}}{{{preceded_by|}}}{{{succeeded_by|}}}{{{new_session|}}}|History}} | label7 = {{#if:{{{foundation|}}}|จัดตั้ง|สถาปนา}} | data7 = {{#if:{{{foundation|}}}|{{{foundation}}}|{{{established|}}}}} | label8 = Disbanded | data8 = {{{disbanded|}}} | label9 = Preceded&nbsp;by | data9 = {{{preceded_by|}}} | label10 = Succeeded&nbsp;by | data10 = {{{succeeded_by|}}} | label11 = {{longitem|New session started}} | data11 = {{{new_session|}}} | header14 = {{#if:{{{leader1|}}}{{{leader2|}}}{{{leader3|}}}{{{leader4|}}}{{{leader5|}}}{{{leader6|}}}{{{leader7|}}}{{{leader8|}}}|ผู้บริหาร}} | label15 = {{longitem|{{{leader1_type|}}}}} | data15 = {{#if:{{{leader1|}}} |{{longitem|style=line-height:1.3em|{{{leader1|}}}{{#if:{{{party1|}}}|{{#ifeq:{{Str index|{{{party1|}}}|1}}|(||,}}&#32;{{{party1|}}}}} {{#if:{{{election1|}}}|<br/>since {{{election1|}}}|{{#if:{{{leader1_term|}}}|<br/>{{{leader1_term}}}}} }} }} }} | label16 = {{longitem|style=line-height:1.3em|{{{leader2_type|}}}}} | data16 = {{#if:{{{leader2|}}} |{{longitem|style=line-height:1.3em|{{{leader2|}}}{{#if:{{{party2|}}}|{{#ifeq:{{Str index|{{{party2|}}}|1}}|(||,}}&#32;{{{party2|}}}}} {{#if:{{{election2|}}}|<br/>since {{{election2|}}}|{{#if:{{{leader2_term|}}}|<br/>{{{leader2_term}}}}} }} }} }} | label17 = {{longitem|style=line-height:1.3em|{{{leader3_type|}}}}} | data17 = {{#if:{{{leader3|}}} |{{longitem|style=line-height:1.3em|{{{leader3|}}}{{#if:{{{party3|}}}|{{#ifeq:{{Str index|{{{party3|}}}|1}}|(||,}}&#32;{{{party3|}}}}} {{#if:{{{election3|}}}|<br/>since {{{election3|}}}|{{#if:{{{leader3_term|}}}|<br/>{{{leader3_term}}}}} }} }} }} | label18 = {{longitem|style=line-height:1.3em|{{{leader4_type|}}}}} | data18 = {{#if:{{{leader4|}}} |{{longitem|style=line-height:1.3em|{{{leader4|}}}{{#if:{{{party4|}}}|{{#ifeq:{{Str index|{{{party4|}}}|1}}|(||,}}&#32;{{{party4|}}}}} {{#if:{{{election4|}}}|<br/>since {{{election4|}}}|{{#if:{{{leader4_term|}}}|<br/>{{{leader4_term}}}}} }} }} }} | label19 = {{longitem|style=line-height:1.3em|{{{leader5_type|}}}}} | data19 = {{#if:{{{leader5|}}} |{{longitem|style=line-height:1.3em|{{{leader5|}}}{{#if:{{{party5|}}}|{{#ifeq:{{Str index|{{{party5|}}}|1}}|(||,}}&#32;{{{party5|}}}}} {{#if:{{{election5|}}}|<br/>since {{{election5|}}}|{{#if:{{{leader5_term|}}}|<br/>{{{leader5_term}}}}} }} }} }} | label20 = {{longitem|style=line-height:1.3em|{{{leader6_type|}}}}} | data20 = {{#if:{{{leader6|}}} |{{longitem|style=line-height:1.3em|{{{leader6|}}}{{#if:{{{party6|}}}|{{#ifeq:{{Str index|{{{party6|}}}|1}}|(||,}}&#32;{{{party6|}}}}} {{#if:{{{election6|}}}|<br/>since {{{election6|}}}|{{#if:{{{leader6_term|}}}|<br/>{{{leader6_term}}}}} }} }} }} | label21 = {{longitem|style=line-height:1.3em|{{{leader7_type|}}}}} | data21 = {{#if:{{{leader7|}}} |{{longitem|style=line-height:1.3em|{{{leader7|}}}{{#if:{{{party7|}}}|{{#ifeq:{{Str index|{{{party7|}}}|1}}|(||,}}&#32;{{{party7|}}}}} {{#if:{{{election7|}}}|<br/>since {{{election7|}}}|{{#if:{{{leader7_term|}}}|<br/>{{{leader7_term}}}}} }} }} }} | label22 = {{longitem|style=line-height:1.3em|{{{leader8_type|}}}}} | data22 = {{#if:{{{leader8|}}} |{{longitem|style=line-height:1.3em|{{{leader8|}}}{{#if:{{{party8|}}}|{{#ifeq:{{Str index|{{{party8|}}}|1}}|(||,}}&#32;{{{party8|}}}}} {{#if:{{{election8|}}}|<br/>since {{{election8|}}}|{{#if:{{{leader8_term|}}}|<br/>{{{leader8_term}}}}} }} }} }} | label23 = {{longitem|style=line-height:1.3em|{{{leader9_type|}}}}} | data23 = {{#if:{{{leader9|}}} |{{longitem|style=line-height:1.3em|{{{leader9|}}}{{#if:{{{party9|}}}|{{#ifeq:{{Str index|{{{party9|}}}|1}}|(||,}}&#32;{{{party9|}}}}} {{#if:{{{election9|}}}|<br/>since {{{election9|}}}|{{#if:{{{leader9_term|}}}|<br/>{{{leader9_term}}}}} }} }} }} | label24 = {{longitem|style=line-height:1.3em|{{{leader10_type|}}}}} | data24 = {{#if:{{{leader10|}}} |{{longitem|style=line-height:1.3em|{{{leader10|}}}{{#if:{{{party10|}}}|{{#ifeq:{{Str index|{{{party10|}}}|1}}|(||,}}&#32;{{{party10|}}}}} {{#if:{{{election10|}}}|<br/>ตั้งแต่ {{{election10|}}}|{{#if:{{{leader10_term|}}}|<br/>{{{leader10_term}}}}} }} }} }} | header25 = {{#if:{{{structure1|}}}{{{political_groups1|}}}{{{structure2|}}}{{{political_groups2|}}}{{{committees1|}}}{{{committees2|}}}{{{joint_committees|}}}{{{term_length|}}}{{{authority|}}}{{{salary|}}} {{{seats1|}}}{{{seats2|}}}{{{seats3|}}}{{{seats4|}}}{{{seats5|}}}{{{seats6|}}}{{{seats7|}}}{{{seats8|}}}|โครงสร้าง}} | label26 = สมาชิก | data26 = {{#if:{{{members|}}}|{{{members}}}|{{{seats|}}}}} | data27 = {{#invoke:InfoboxImage|InfoboxImage|image={{{structure1|}}}|size={{{structure1_res|}}}|sizedefault=120px|alt={{{structure1_alt|}}}}} | label28 = {{longitem|{{#if:{{{house1|}}}|กลุ่มการเมือง{{{house1}}}|กลุ่มการเมือง}}}} | data28 = {{{political_groups1|}}} | data29 = {{#invoke:InfoboxImage|InfoboxImage|image={{{structure2|}}}|size={{{structure2_res|}}}|sizedefault=120px|alt={{{structure2_alt|}}}}} | label30 = {{longitem|{{#if:{{{house2|}}}|กลุ่มการเมือง{{{house2}}}|กลุ่มการเมือง}}}} | data30 = {{{political_groups2|}}} | label31 = {{#if:{{{house1|}}}|{{{house1}}} committees|Committees}} | data31 = {{{committees1|}}} | label32 = {{#if:{{{house2|}}}|{{{house2}}} committees|Committees}} | data32 = {{{committees2|}}} | label33 = {{longitem|Joint committees}} | data33 = {{{joint_committees|}}} | label34 = {{longitem|Length of term}} | data34 = {{{term_length|}}} | label35 = Authority | data35 = {{{authority|}}} | label36 = Salary | data36 = {{{salary|}}} | label37 = {{longitem|{{{seats1_title|}}}}} | data37 = {{{seats1|}}} | label38 = {{longitem|{{{seats2_title|}}}}} | data38 = {{{seats2|}}} | label39 = {{longitem|{{{seats3_title|}}}}} | data39 = {{{seats3|}}} | label40 = {{longitem|{{{seats4_title|}}}}} | data40 = {{{seats4|}}} | label41 = {{longitem|{{{seats5_title|}}}}} | data41 = {{{seats5|}}} | label42 = {{longitem|{{{seats6_title|}}}}} | data42 = {{{seats6|}}} | label43 = {{longitem|{{{seats7_title|}}}}} | data43 = {{{seats7|}}} | label44 = {{longitem|{{{seats8_title|}}}}} | data44 = {{{seats8|}}} | label45 = {{longitem|{{{seats9_title|}}}}} | data45 = {{{seats9|}}} | label46 = {{longitem|{{{seats10_title|}}}}} | data46 = {{{seats10|}}} | header47 = {{#if:{{{voting_system1|}}}{{{voting_system2|}}}{{{first_election1|}}}{{{first_election2|}}}{{{first_election3|}}}{{{last_election1|}}}{{{last_election2|}}}{{{last_election3|}}}{{{next_election1|}}}{{{next_election2|}}}{{{next_election3|}}}{{{redistricting|}}}|การเลือกตั้ง}} | label48 = {{longitem|{{#if:{{{house1|}}}|{{{house1}}} [[electoral system|voting system]]|[[electoral system|Voting system]]}}}} | data48 = {{{voting_system1|}}} | label49 = {{longitem|{{#if:{{{house2|}}}|{{{house2}}} [[electoral system|voting system]]|[[electoral system|Voting system]]}}}} | data49 = {{{voting_system2|}}} | label50 = {{longitem|{{#if:{{{house1|}}}|First {{{house1}}} election|First election}}}} | data50 = {{{first_election1|}}} | label51 = {{longitem|{{#if:{{{house2|}}}|First {{{house2}}} election|First election}}}} | data51 = {{{first_election2|}}} | label52 = {{longitem|First general election}} | data52 = {{{first_election3|}}} | label53 = {{longitem|{{#if:{{{house1|}}}|Last {{{house1}}} election|Last election}}}} | data53 = {{{last_election1|}}} | label54 = {{longitem|{{#if:{{{house2|}}}|Last {{{house2}}} election|Last election}}}} | data54 = {{{last_election2|}}} | label55 = {{longitem|Last general election}} | data55 = {{{last_election3|}}} | label56 = {{longitem|{{#if:{{{house1|}}}|Next {{{house1}}} election|Next election}}}} | data56 = {{{next_election1|}}} | label57 = {{longitem|{{#if:{{{house2|}}}|Next {{{house2}}} election|Next election}}}} | data57 = {{{next_election2|}}} | label58 = {{longitem|Next general election}} | data58 = {{{next_election3|}}} | label59 = Redistricting | data59 = {{{redistricting|}}} | header60 = {{#if:{{{motto|}}}|Motto}} | data61 = {{{motto|}}} | header62 = {{#if:{{{session_room|}}}{{{meeting_place|}}}|ที่ประชุม}} | data63 = {{#invoke:InfoboxImage|InfoboxImage|image={{{session_room|}}}|size={{{session_res|}}}|alt={{{session_alt|}}}}} | data64 = {{{meeting_place|}}} | class64 = label | data65 = {{#invoke:InfoboxImage|InfoboxImage|image={{{session_room2|}}}|size={{{session_res2|}}}|alt={{{session_alt2|}}}}} | data66 = {{{meeting_place2|}}} | class66 = label | data67 = {{#invoke:InfoboxImage|InfoboxImage|image={{{session_room3|}}}|size={{{session_res3|}}}|alt={{{session_alt3|}}}}} | data68 = {{{meeting_place3|}}} | class68 = label | header69 = {{#if:{{{website|}}}|เว็บไซต์}} | data70 = {{{website|}}} | header71 = {{#if:{{{constitution|}}}|รัฐธรรมนูญ}} | data72 = {{{constitution|}}} | header73 = {{#if:{{{rules|}}}|Rules}} | data74 = {{{rules|}}} | header75 = {{#if:{{{footnotes|}}}|หมายเหตุ}} | data76 = {{{footnotes|}}} }}{{Main other|{{#if:{{{background_color|}}}{{{text_color|}}}|[[Category:Infobox legislature with background color]]}}}}{{#invoke:Check for unknown parameters|check|unknown={{main other|}}|preview=Page using [[Template:Infobox legislature]] with unknown parameter "_VALUE_"|ignoreblank=y| authority | background_color | body | categories | chambers | coa_alt | coa_caption | coa_pic | coa_res | coa-alt | coa-pic | coa-res | committees1 | committees2 | constitution | demo | disbanded | election1 | election2 | election3 | election4 | election5 | election6 | election7 | election8 | election9 | election10 | established | first_election1 | first_election2 | first_election3 | footnotes | foundation | house_type | house1 | house2 | houses | joint_committees | jurisdiction | labelstyle | last_election1 | last_election2 | last_election3 | leader1 | leader1_type | leader2 | leader2_type | leader3 | leader3_type | leader4 | leader4_type | leader5 | leader5_type | leader6 | leader6_type | leader7 | leader7_type | leader8 | leader8_type | leader9 | leader9_type | leader10 | leader10_type | legislature | logo | logo_alt | logo_caption | logo_pic | logo_res | logo-alt | logo-pic | logo-res | meeting_place | meeting_place2 | meeting_place3 | members | motto | name | native_name | native_name_lang | new_session | next_election1 | next_election2 | next_election3 | nocat | party1 | party2 | party3 | party4 | party5 | party6 | party7 | party8 | party9 | party10 | political_groups1 | political_groups2 | preceded_by | redistricting | rules | salary | seats | seats1 | seats1_title | seats2 | seats2_title | seats3 | seats3_title | seats4 | seats4_title | seats5 | seats5_title | seats6 | seats6_title | seats7 | seats7_title | seats8 | seats8_title | session_alt | session_alt2 | session_alt3 | session_res | session_res2 | session_res3 | session_room | session_room2 | session_room3 | structure1 | structure1_alt | structure1_res | structure2 | structure2_alt | structure2_res | succeeded_by | term_length | term_limits | text_color | transcription_name | voting_system1 | voting_system2 | website }}<noinclude> {{documentation}}<!--Please add this template's categories to the /doc subpage, not here - thanks!--> </noinclude> 7e3d618b24a2e0360bcaa2083bb8d4548f550c0c แม่แบบ:Infobox 10 70 129 2023-10-05T15:26:31Z PeachFullzZ 2 สร้างหน้าด้วย "{{#invoke:Infobox|infobox}}<includeonly>{{template other|{{#ifeq:{{PAGENAME}}|Infobox||{{#ifeq:{{str left|{{SUBPAGENAME}}|7}}|Infobox|[[Category:Infobox templates|{{remove first word|{{SUBPAGENAME}}}}]]}}}}|}}</includeonly><noinclude> {{documentation}} <!-- Categories go in the /doc subpage, and interwikis go in Wikidata. --> </noinclude>" wikitext text/x-wiki {{#invoke:Infobox|infobox}}<includeonly>{{template other|{{#ifeq:{{PAGENAME}}|Infobox||{{#ifeq:{{str left|{{SUBPAGENAME}}|7}}|Infobox|[[Category:Infobox templates|{{remove first word|{{SUBPAGENAME}}}}]]}}}}|}}</includeonly><noinclude> {{documentation}} <!-- Categories go in the /doc subpage, and interwikis go in Wikidata. --> </noinclude> 817a9f5b6524eced06a57bd1d5fd7179f9369bf2 130 129 2023-10-05T15:26:47Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Infobox]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki {{#invoke:Infobox|infobox}}<includeonly>{{template other|{{#ifeq:{{PAGENAME}}|Infobox||{{#ifeq:{{str left|{{SUBPAGENAME}}|7}}|Infobox|[[Category:Infobox templates|{{remove first word|{{SUBPAGENAME}}}}]]}}}}|}}</includeonly><noinclude> {{documentation}} <!-- Categories go in the /doc subpage, and interwikis go in Wikidata. --> </noinclude> 817a9f5b6524eced06a57bd1d5fd7179f9369bf2 แม่แบบ:Template other 10 71 131 2023-10-05T15:27:51Z PeachFullzZ 2 สร้างหน้าด้วย "{{#switch: <!--If no or empty "demospace" parameter then detect namespace--> {{#if:{{{demospace|}}} | {{lc: {{{demospace}}} }} <!--Use lower case "demospace"--> | {{#ifeq:{{NAMESPACE}}|{{ns:Template}} | template | other }} }} | template = {{{1|}}} | other | #default = {{{2|}}} }}<!--End switch--><noinclude> {{documentation}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude>" wikitext text/x-wiki {{#switch: <!--If no or empty "demospace" parameter then detect namespace--> {{#if:{{{demospace|}}} | {{lc: {{{demospace}}} }} <!--Use lower case "demospace"--> | {{#ifeq:{{NAMESPACE}}|{{ns:Template}} | template | other }} }} | template = {{{1|}}} | other | #default = {{{2|}}} }}<!--End switch--><noinclude> {{documentation}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 06fb13d264df967b5232141067eb7d2b67372d76 132 131 2023-10-05T15:28:02Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Template other]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki {{#switch: <!--If no or empty "demospace" parameter then detect namespace--> {{#if:{{{demospace|}}} | {{lc: {{{demospace}}} }} <!--Use lower case "demospace"--> | {{#ifeq:{{NAMESPACE}}|{{ns:Template}} | template | other }} }} | template = {{{1|}}} | other | #default = {{{2|}}} }}<!--End switch--><noinclude> {{documentation}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 06fb13d264df967b5232141067eb7d2b67372d76 แม่แบบ:URL 10 72 133 2023-10-05T15:30:43Z PeachFullzZ 2 สร้างหน้าด้วย "<includeonly>{{#invoke:URL|url}}</includeonly>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using URL template with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:URL]] with unknown parameter "_VALUE_"|ignoreblank=y | 1 | 2 }}<noinclude>{{documentation}}</noinclude>" wikitext text/x-wiki <includeonly>{{#invoke:URL|url}}</includeonly>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using URL template with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:URL]] with unknown parameter "_VALUE_"|ignoreblank=y | 1 | 2 }}<noinclude>{{documentation}}</noinclude> 5671474ce4656f07c5bdc47292d1dcbe9c70317e 134 133 2023-10-05T15:31:00Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:URL]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki <includeonly>{{#invoke:URL|url}}</includeonly>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using URL template with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:URL]] with unknown parameter "_VALUE_"|ignoreblank=y | 1 | 2 }}<noinclude>{{documentation}}</noinclude> 5671474ce4656f07c5bdc47292d1dcbe9c70317e มอดูล:URL 828 73 135 2023-10-05T15:32:00Z PeachFullzZ 2 สร้างหน้าด้วย "-- -- This module implements {{URL}} -- -- See unit tests at [[Module:URL/testcases]] local p = {} local function safeUri(s) local success, uri = pcall(function() return mw.uri.new(s) end) if success then return uri end end local function extractUrl(args) for name, val in pairs(args) do if name ~= 2 and name ~= "msg" then local url = name .. "=" .. val; url = mw.ustring.gsub(url, '^[Hh][Tt][Tt][Pp]([Ss]?):(/?)([^/])', 'http%1://..." Scribunto text/plain -- -- This module implements {{URL}} -- -- See unit tests at [[Module:URL/testcases]] local p = {} local function safeUri(s) local success, uri = pcall(function() return mw.uri.new(s) end) if success then return uri end end local function extractUrl(args) for name, val in pairs(args) do if name ~= 2 and name ~= "msg" then local url = name .. "=" .. val; url = mw.ustring.gsub(url, '^[Hh][Tt][Tt][Pp]([Ss]?):(/?)([^/])', 'http%1://%3') local uri = safeUri(url); if uri and uri.host then return url end end end end function p._url(url, text, msg) url = mw.text.trim(url or '') text = mw.text.trim(text or '') local nomsg = (msg or ''):sub(1,1):lower() == "n" or msg == 'false' -- boolean: true if msg is "false" or starts with n or N if url == '' then if text == '' then if nomsg then return nil else return mw.getCurrentFrame():expandTemplate{ title = 'tlx', args = { 'URL', "''example.com''", "''optional display text''" } } end else return text end end -- If the URL contains any unencoded spaces, encode them, because MediaWiki will otherwise interpret a space as the end of the URL. url = mw.ustring.gsub(url, '%s', function(s) return mw.uri.encode(s, 'PATH') end) -- If there is an empty query string or fragment id, remove it as it will cause mw.uri.new to throw an error url = mw.ustring.gsub(url, '#$', '') url = mw.ustring.gsub(url, '%?$', '') -- If it's an HTTP[S] URL without the double slash, fix it. url = mw.ustring.gsub(url, '^[Hh][Tt][Tt][Pp]([Ss]?):(/?)([^/])', 'http%1://%3') local uri = safeUri(url) -- Handle URL's without a protocol and URL's that are protocol-relative, -- e.g. www.example.com/foo or www.example.com:8080/foo, and //www.example.com/foo if uri and (not uri.protocol or (uri.protocol and not uri.host)) and url:sub(1, 2) ~= '//' then url = 'http://' .. url uri = safeUri(url) end if text == '' then if uri then if uri.path == '/' then uri.path = '' end local port = '' if uri.port then port = ':' .. uri.port end text = mw.ustring.lower(uri.host or '') .. port .. (uri.relativePath or '') -- Add <wbr> before _/.-# sequences text = mw.ustring.gsub(text,"(/+)","<wbr/>%1") -- This entry MUST be the first. "<wbr/>" has a "/" in it, you know. text = mw.ustring.gsub(text,"(%.+)","<wbr/>%1") -- text = mw.ustring.gsub(text,"(%-+)","<wbr/>%1") -- DISABLED for now text = mw.ustring.gsub(text,"(%#+)","<wbr/>%1") text = mw.ustring.gsub(text,"(_+)","<wbr/>%1") else -- URL is badly-formed, so just display whatever was passed in text = url end end return mw.ustring.format('<span class="url">[%s %s]</span>', url, text) end --[[ The main entry point for calling from Template:URL. --]] function p.url(frame) local templateArgs = frame.args local parentArgs = frame:getParent().args local url = templateArgs[1] or parentArgs[1] local text = templateArgs[2] or parentArgs[2] or '' local msg = templateArgs.msg or parentArgs.msg or '' url = url or extractUrl(templateArgs) or extractUrl(parentArgs) or '' return p._url(url, text, msg) end --[[ The entry point for calling from the forked Template:URL2. This function returns no message by default. It strips out wiki-link markup, html tags, and everything after a space. --]] function p.url2(frame) local templateArgs = frame.args local parentArgs = frame:getParent().args local url = templateArgs[1] or parentArgs[1] local text = templateArgs[2] or parentArgs[2] or '' -- default to no message local msg = templateArgs.msg or parentArgs.msg or 'no' url = url or extractUrl(templateArgs) or extractUrl(parentArgs) or '' -- if the url came from a Wikidata call, it might have a pen icon appended -- we want to keep that and add it back at the end. local u1, penicon = mw.ustring.match( url, "(.*)(&nbsp;<span class='penicon.*)" ) if penicon then url = u1 end -- strip out html tags and [ ] from url url = (url or ''):gsub("<[^>]*>", ""):gsub("[%[%]]", "") -- truncate anything after a space url = url:gsub("%%20", " "):gsub(" .*", "") return (p._url(url, text, msg) or "") .. (penicon or "") end return p 8d7a4c6fe04a01815e940475cf64b28e1ef48cfb 136 135 2023-10-05T15:32:13Z PeachFullzZ 2 ป้องกัน "[[มอดูล:URL]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- -- This module implements {{URL}} -- -- See unit tests at [[Module:URL/testcases]] local p = {} local function safeUri(s) local success, uri = pcall(function() return mw.uri.new(s) end) if success then return uri end end local function extractUrl(args) for name, val in pairs(args) do if name ~= 2 and name ~= "msg" then local url = name .. "=" .. val; url = mw.ustring.gsub(url, '^[Hh][Tt][Tt][Pp]([Ss]?):(/?)([^/])', 'http%1://%3') local uri = safeUri(url); if uri and uri.host then return url end end end end function p._url(url, text, msg) url = mw.text.trim(url or '') text = mw.text.trim(text or '') local nomsg = (msg or ''):sub(1,1):lower() == "n" or msg == 'false' -- boolean: true if msg is "false" or starts with n or N if url == '' then if text == '' then if nomsg then return nil else return mw.getCurrentFrame():expandTemplate{ title = 'tlx', args = { 'URL', "''example.com''", "''optional display text''" } } end else return text end end -- If the URL contains any unencoded spaces, encode them, because MediaWiki will otherwise interpret a space as the end of the URL. url = mw.ustring.gsub(url, '%s', function(s) return mw.uri.encode(s, 'PATH') end) -- If there is an empty query string or fragment id, remove it as it will cause mw.uri.new to throw an error url = mw.ustring.gsub(url, '#$', '') url = mw.ustring.gsub(url, '%?$', '') -- If it's an HTTP[S] URL without the double slash, fix it. url = mw.ustring.gsub(url, '^[Hh][Tt][Tt][Pp]([Ss]?):(/?)([^/])', 'http%1://%3') local uri = safeUri(url) -- Handle URL's without a protocol and URL's that are protocol-relative, -- e.g. www.example.com/foo or www.example.com:8080/foo, and //www.example.com/foo if uri and (not uri.protocol or (uri.protocol and not uri.host)) and url:sub(1, 2) ~= '//' then url = 'http://' .. url uri = safeUri(url) end if text == '' then if uri then if uri.path == '/' then uri.path = '' end local port = '' if uri.port then port = ':' .. uri.port end text = mw.ustring.lower(uri.host or '') .. port .. (uri.relativePath or '') -- Add <wbr> before _/.-# sequences text = mw.ustring.gsub(text,"(/+)","<wbr/>%1") -- This entry MUST be the first. "<wbr/>" has a "/" in it, you know. text = mw.ustring.gsub(text,"(%.+)","<wbr/>%1") -- text = mw.ustring.gsub(text,"(%-+)","<wbr/>%1") -- DISABLED for now text = mw.ustring.gsub(text,"(%#+)","<wbr/>%1") text = mw.ustring.gsub(text,"(_+)","<wbr/>%1") else -- URL is badly-formed, so just display whatever was passed in text = url end end return mw.ustring.format('<span class="url">[%s %s]</span>', url, text) end --[[ The main entry point for calling from Template:URL. --]] function p.url(frame) local templateArgs = frame.args local parentArgs = frame:getParent().args local url = templateArgs[1] or parentArgs[1] local text = templateArgs[2] or parentArgs[2] or '' local msg = templateArgs.msg or parentArgs.msg or '' url = url or extractUrl(templateArgs) or extractUrl(parentArgs) or '' return p._url(url, text, msg) end --[[ The entry point for calling from the forked Template:URL2. This function returns no message by default. It strips out wiki-link markup, html tags, and everything after a space. --]] function p.url2(frame) local templateArgs = frame.args local parentArgs = frame:getParent().args local url = templateArgs[1] or parentArgs[1] local text = templateArgs[2] or parentArgs[2] or '' -- default to no message local msg = templateArgs.msg or parentArgs.msg or 'no' url = url or extractUrl(templateArgs) or extractUrl(parentArgs) or '' -- if the url came from a Wikidata call, it might have a pen icon appended -- we want to keep that and add it back at the end. local u1, penicon = mw.ustring.match( url, "(.*)(&nbsp;<span class='penicon.*)" ) if penicon then url = u1 end -- strip out html tags and [ ] from url url = (url or ''):gsub("<[^>]*>", ""):gsub("[%[%]]", "") -- truncate anything after a space url = url:gsub("%%20", " "):gsub(" .*", "") return (p._url(url, text, msg) or "") .. (penicon or "") end return p 8d7a4c6fe04a01815e940475cf64b28e1ef48cfb แม่แบบ:Longitem 10 74 137 2023-10-05T15:36:45Z PeachFullzZ 2 สร้างหน้าด้วย "<noinclude>{{#tag: code| </noinclude>{{#ifeq: {{{1|+}}} | {{{1|-}}} | <div style="}}display: inline-block; line-height: 1.2em; padding: .1em 0; {{#ifeq: {{{1|+}}} | {{{1|-}}} | {{{style|}}}">{{{1|}}}</div> | <includeonly>width: 100%;</includeonly> }}<includeonly>{{#if:{{{2|}}}|[[Category:Pages using Template:Longitem with unnamed style parameter]]}}</includeonly><noinclude> |lang=wikitext}} {{documentation}} </noinclude>" wikitext text/x-wiki <noinclude>{{#tag: code| </noinclude>{{#ifeq: {{{1|+}}} | {{{1|-}}} | <div style="}}display: inline-block; line-height: 1.2em; padding: .1em 0; {{#ifeq: {{{1|+}}} | {{{1|-}}} | {{{style|}}}">{{{1|}}}</div> | <includeonly>width: 100%;</includeonly> }}<includeonly>{{#if:{{{2|}}}|[[Category:Pages using Template:Longitem with unnamed style parameter]]}}</includeonly><noinclude> |lang=wikitext}} {{documentation}} </noinclude> ee535abe443dff124966cf5159c50aa2271e9cde 138 137 2023-10-05T15:37:00Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Longitem]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki <noinclude>{{#tag: code| </noinclude>{{#ifeq: {{{1|+}}} | {{{1|-}}} | <div style="}}display: inline-block; line-height: 1.2em; padding: .1em 0; {{#ifeq: {{{1|+}}} | {{{1|-}}} | {{{style|}}}">{{{1|}}}</div> | <includeonly>width: 100%;</includeonly> }}<includeonly>{{#if:{{{2|}}}|[[Category:Pages using Template:Longitem with unnamed style parameter]]}}</includeonly><noinclude> |lang=wikitext}} {{documentation}} </noinclude> ee535abe443dff124966cf5159c50aa2271e9cde แม่แบบ:Colorbox 10 75 139 2023-10-05T15:39:32Z PeachFullzZ 2 เปลี่ยนทางหน้าไปยัง [[แม่แบบ:Color box]] wikitext text/x-wiki #REDIRECT [[Template:Color box]] {{Redirect category shell| {{R from merge}} {{R from template shortcut}} {{R from modification}} }} a154607198487fcef1e49a08eb2a209d9712f35b 140 139 2023-10-05T15:39:58Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Colorbox]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki #REDIRECT [[Template:Color box]] {{Redirect category shell| {{R from merge}} {{R from template shortcut}} {{R from modification}} }} a154607198487fcef1e49a08eb2a209d9712f35b แม่แบบ:Color box 10 76 141 2023-10-05T15:40:29Z PeachFullzZ 2 สร้างหน้าด้วย "<templatestyles src="Legend/styles.css" /><span class="legend-color" style="{{#if:{{{1|}}}|{{greater color contrast ratio|{{{1}}}|black|white|css=y}} }}{{#if:{{{3|}}}|color:{{{3}}}; }}{{#if:{{{border|}}}|border:1px solid {{{border}}}; }}{{#if:{{{padding|}}}|padding:{{{padding}}};}}">{{#if:{{{2|}}} |{{#if:{{{padding|}}}|{{{2}}}|&nbsp;{{{2}}}&nbsp;}} |&nbsp;}}</span><noinclude> {{documentation}}</noinclude>" wikitext text/x-wiki <templatestyles src="Legend/styles.css" /><span class="legend-color" style="{{#if:{{{1|}}}|{{greater color contrast ratio|{{{1}}}|black|white|css=y}} }}{{#if:{{{3|}}}|color:{{{3}}}; }}{{#if:{{{border|}}}|border:1px solid {{{border}}}; }}{{#if:{{{padding|}}}|padding:{{{padding}}};}}">{{#if:{{{2|}}} |{{#if:{{{padding|}}}|{{{2}}}|&nbsp;{{{2}}}&nbsp;}} |&nbsp;}}</span><noinclude> {{documentation}}</noinclude> 3ae512cce09eab9e599e79e21b13c0190a5f3e27 แม่แบบ:Legend/styles.css 10 77 142 2023-10-05T15:41:24Z PeachFullzZ 2 สร้างหน้าด้วย "/* {{pp-template}} */ .legend { page-break-inside: avoid; break-inside: avoid-column; } .legend-color { display: inline-block; min-width: 1.25em; height: 1.25em; line-height: 1.25; margin: 1px 0; text-align: center; border: 1px solid black; background-color: transparent; color: black; } .legend-text {/*empty for now, but part of the design!*/}" sanitized-css text/css /* {{pp-template}} */ .legend { page-break-inside: avoid; break-inside: avoid-column; } .legend-color { display: inline-block; min-width: 1.25em; height: 1.25em; line-height: 1.25; margin: 1px 0; text-align: center; border: 1px solid black; background-color: transparent; color: black; } .legend-text {/*empty for now, but part of the design!*/} f55cad65402533fc931db7fefc801536194952d7 143 142 2023-10-05T15:41:41Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Legend/styles.css]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) sanitized-css text/css /* {{pp-template}} */ .legend { page-break-inside: avoid; break-inside: avoid-column; } .legend-color { display: inline-block; min-width: 1.25em; height: 1.25em; line-height: 1.25; margin: 1px 0; text-align: center; border: 1px solid black; background-color: transparent; color: black; } .legend-text {/*empty for now, but part of the design!*/} f55cad65402533fc931db7fefc801536194952d7 แม่แบบ:Legend 10 78 145 2023-10-05T15:57:28Z PeachFullzZ 2 สร้างหน้าด้วย "<includeonly><!-- --><templatestyles src="Legend/styles.css" /><!-- --><div class="legend"><!-- --><span class="legend-color mw-no-invert" style="<!-- -->{{#if:{{{border|}}}|border: {{{border}}};|{{#if:{{{outline|}}}|border: 1px solid {{{outline}}};}}}}<!-- -->{{#if:{{{1|}}}|{{greater color contrast ratio|{{{1}}}|white|black|css=y}}}}<!-- -->{{#if:{{{textcolor|}}}|color:{{{textcolor}}};}}<!-- -->{{#if:{{{size|}}}|font-size:{{{size}}};}}"><!--..." wikitext text/x-wiki <includeonly><!-- --><templatestyles src="Legend/styles.css" /><!-- --><div class="legend"><!-- --><span class="legend-color mw-no-invert" style="<!-- -->{{#if:{{{border|}}}|border: {{{border}}};|{{#if:{{{outline|}}}|border: 1px solid {{{outline}}};}}}}<!-- -->{{#if:{{{1|}}}|{{greater color contrast ratio|{{{1}}}|white|black|css=y}}}}<!-- -->{{#if:{{{textcolor|}}}|color:{{{textcolor}}};}}<!-- -->{{#if:{{{size|}}}|font-size:{{{size}}};}}"><!-- -->{{#if:{{{text|}}}{{{alt|}}} | <span class="legend-text" style="{{#if:{{{alt|}}}|color:{{{1|}}};}}font-family: monospace, monospace;">{{If empty|{{{alt|}}}|{{{text|}}}|&nbsp;}}</span>|&nbsp;}}<!-- --></span><!-- -->&nbsp;{{{2|}}}<!-- --></div><!-- --></includeonly><noinclude> {{Documentation}} </noinclude> bbd1ff4b07414421f82b44f2eabe760b816e56e2 146 145 2023-10-05T15:57:56Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Legend]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki <includeonly><!-- --><templatestyles src="Legend/styles.css" /><!-- --><div class="legend"><!-- --><span class="legend-color mw-no-invert" style="<!-- -->{{#if:{{{border|}}}|border: {{{border}}};|{{#if:{{{outline|}}}|border: 1px solid {{{outline}}};}}}}<!-- -->{{#if:{{{1|}}}|{{greater color contrast ratio|{{{1}}}|white|black|css=y}}}}<!-- -->{{#if:{{{textcolor|}}}|color:{{{textcolor}}};}}<!-- -->{{#if:{{{size|}}}|font-size:{{{size}}};}}"><!-- -->{{#if:{{{text|}}}{{{alt|}}} | <span class="legend-text" style="{{#if:{{{alt|}}}|color:{{{1|}}};}}font-family: monospace, monospace;">{{If empty|{{{alt|}}}|{{{text|}}}|&nbsp;}}</span>|&nbsp;}}<!-- --></span><!-- -->&nbsp;{{{2|}}}<!-- --></div><!-- --></includeonly><noinclude> {{Documentation}} </noinclude> bbd1ff4b07414421f82b44f2eabe760b816e56e2 ไฟล์:National Legislative Assembly of Thailand (2023).svg 6 79 152 2023-10-05T16:45:16Z PeachFullzZ 2 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 แม่แบบ:Background color 10 80 153 2023-10-05T16:49:27Z PeachFullzZ 2 สร้างหน้าด้วย "<span style="background-color: {{{c|{{{1|}}}}}}">{{{t|{{{2|}}}}}}</span>{{Main other|{{Ensure AAA contrast ratio|base={{{c|{{{1|}}}}}}|other={{{t|{{{2|}}}}}}|category=[[Category:Articles using Template:Background color with invalid colour combination]]}}}}{{Template other|{{Ensure AAA contrast ratio|base={{{c|{{{1|}}}}}}|other={{{t|{{{2|}}}}}}|category=[[Category:Articles using Template:Background color with invalid colour combination]]}}}}<noinclud..." wikitext text/x-wiki <span style="background-color: {{{c|{{{1|}}}}}}">{{{t|{{{2|}}}}}}</span>{{Main other|{{Ensure AAA contrast ratio|base={{{c|{{{1|}}}}}}|other={{{t|{{{2|}}}}}}|category=[[Category:Articles using Template:Background color with invalid colour combination]]}}}}{{Template other|{{Ensure AAA contrast ratio|base={{{c|{{{1|}}}}}}|other={{{t|{{{2|}}}}}}|category=[[Category:Articles using Template:Background color with invalid colour combination]]}}}}<noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES TO THE /doc SUBPAGE, THANKS --> </noinclude> 5728037c420652a17d1d3229dcbb4217d2378d7f 154 153 2023-10-05T16:49:43Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Background color]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki <span style="background-color: {{{c|{{{1|}}}}}}">{{{t|{{{2|}}}}}}</span>{{Main other|{{Ensure AAA contrast ratio|base={{{c|{{{1|}}}}}}|other={{{t|{{{2|}}}}}}|category=[[Category:Articles using Template:Background color with invalid colour combination]]}}}}{{Template other|{{Ensure AAA contrast ratio|base={{{c|{{{1|}}}}}}|other={{{t|{{{2|}}}}}}|category=[[Category:Articles using Template:Background color with invalid colour combination]]}}}}<noinclude> {{Documentation}} <!-- PLEASE ADD THIS TEMPLATE'S CATEGORIES TO THE /doc SUBPAGE, THANKS --> </noinclude> 5728037c420652a17d1d3229dcbb4217d2378d7f แม่แบบ:Ensure AAA contrast ratio 10 81 155 2023-10-05T16:50:22Z PeachFullzZ 2 สร้างหน้าด้วย "<includeonly>{{#if:{{{base|}}}|{{#ifexpr:{{#invoke:Color contrast|ratio|{{{base}}}|{{{other|}}}|error=21}} < 7 OR {{#invoke:Color contrast|ratio|{{{base}}}|black|error=0}} < 7 AND {{#invoke:Color contrast|ratio|{{{base}}}|white|error=0}} < 7|{{{category|}}}}}}}</includeonly><noinclude> {{Documentation}}</noinclude>" wikitext text/x-wiki <includeonly>{{#if:{{{base|}}}|{{#ifexpr:{{#invoke:Color contrast|ratio|{{{base}}}|{{{other|}}}|error=21}} < 7 OR {{#invoke:Color contrast|ratio|{{{base}}}|black|error=0}} < 7 AND {{#invoke:Color contrast|ratio|{{{base}}}|white|error=0}} < 7|{{{category|}}}}}}}</includeonly><noinclude> {{Documentation}}</noinclude> 4c5e05501f4bd9f8c2801b9849a7a39e49cdaa4b 156 155 2023-10-05T16:50:36Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Ensure AAA contrast ratio]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki <includeonly>{{#if:{{{base|}}}|{{#ifexpr:{{#invoke:Color contrast|ratio|{{{base}}}|{{{other|}}}|error=21}} < 7 OR {{#invoke:Color contrast|ratio|{{{base}}}|black|error=0}} < 7 AND {{#invoke:Color contrast|ratio|{{{base}}}|white|error=0}} < 7|{{{category|}}}}}}}</includeonly><noinclude> {{Documentation}}</noinclude> 4c5e05501f4bd9f8c2801b9849a7a39e49cdaa4b มอดูล:Color 828 82 157 2023-10-05T16:52:20Z PeachFullzZ 2 สร้างหน้าด้วย "-- Introduction: https://colorspace.r-forge.r-project.org/articles/color_spaces.html local p = {} local function isempty(v) return v == nil or v == '' end local function hexToRgb(color) local cleanColor = color:gsub("&#35;", "#"):match('^[%s#]*(.-)[%s;]*$') if (#cleanColor == 6) then return { r = tonumber(string.sub(cleanColor, 1, 2), 16), g = tonumber(string.sub(cleanColor, 3, 4), 16), b = tonumber(string.sub(cleanColor, 5, 6), 16)..." Scribunto text/plain -- Introduction: https://colorspace.r-forge.r-project.org/articles/color_spaces.html local p = {} local function isempty(v) return v == nil or v == '' end local function hexToRgb(color) local cleanColor = color:gsub("&#35;", "#"):match('^[%s#]*(.-)[%s;]*$') if (#cleanColor == 6) then return { r = tonumber(string.sub(cleanColor, 1, 2), 16), g = tonumber(string.sub(cleanColor, 3, 4), 16), b = tonumber(string.sub(cleanColor, 5, 6), 16) } elseif (#cleanColor == 3) then return { r = 17 * tonumber(string.sub(cleanColor, 1, 1), 16), g = 17 * tonumber(string.sub(cleanColor, 2, 2), 16), b = 17 * tonumber(string.sub(cleanColor, 3, 3), 16) } end error("Invalid hexadecimal color " .. cleanColor, 1) end local function round(v) if (v < 0) then return math.ceil(v - 0.5) else return math.floor(v + 0.5) end end local function rgbToHex(r, g, b) return string.format("%02X%02X%02X", round(r), round(g), round(b)) end local function rgbToCmyk(r, g, b) if (r > 255 or g > 255 or b > 255 or r < 0 or g < 0 or b < 0) then error("Color level out of bounds") end local c = 1 - r / 255 local m = 1 - g / 255 local y = 1 - b / 255 local k = math.min(c, m, y) if (k == 1) then c = 0 m = 0 y = 0 else local d = 1 - k c = (c - k) / d m = (m - k) / d y = (y - k) / d end return { c = c * 100, m = m * 100, y = y * 100, k = k * 100 } end local function rgbToHsl(r, g, b) if (r > 255 or g > 255 or b > 255 or r < 0 or g < 0 or b < 0) then error("Color level out of bounds") end local channelMax = math.max(r, g, b) local channelMin = math.min(r, g, b) local range = channelMax - channelMin local h, s if (range == 0) then h = 0 elseif (channelMax == r) then h = 60 * ((g - b) / range) if (h < 0) then h = 360 + h end elseif (channelMax == g) then h = 60 * (2 + (b - r) / range) else h = 60 * (4 + (r - g) / range) end local L = channelMax + channelMin if (L == 0 or L == 510) then s = 0 else s = 100 * range / math.min(L, 510 - L) end return { h = h, s = s, l = L * 50 / 255 } end local function rgbToHsv(r, g, b) if (r > 255 or g > 255 or b > 255 or r < 0 or g < 0 or b < 0) then error("Color level out of bounds") end local channelMax = math.max(r, g, b) local channelMin = math.min(r, g, b) local range = channelMax - channelMin local h, s if (range == 0) then h = 0 elseif (channelMax == r) then h = 60 * ((g - b) / range) if (h < 0) then h = 360 + h end elseif (channelMax == g) then h = 60 * (2 + (b - r) / range) else h = 60 * (4 + (r - g) / range) end if (channelMax == 0) then s = 0 else s = 100 * range / channelMax end return { h = h, s = s, v = channelMax * 100 / 255 } end -- c in [0, 255], condition tweaked for no discontinuity -- http://entropymine.com/imageworsener/srgbformula/ local function toLinear(c) if (c > 10.314300250662591) then return math.pow((c + 14.025) / 269.025, 2.4) else return c / 3294.6 end end local function toNonLinear(c) if (c > 0.00313066844250063) then return 269.025 * math.pow(c, 1.0/2.4) - 14.025 else return 3294.6 * c end end local function srgbToCielchuvD65o2deg(r, g, b) if (r > 255 or g > 255 or b > 255 or r < 0 or g < 0 or b < 0) then error("Color level out of bounds") end local R = toLinear(r) local G = toLinear(g) local B = toLinear(b) -- https://github.com/w3c/csswg-drafts/issues/5922 local X = 0.1804807884018343 * B + 0.357584339383878 * G + 0.41239079926595934 * R local Y = 0.07219231536073371 * B + 0.21263900587151027 * R + 0.715168678767756 * G local Z = 0.01933081871559182 * R + 0.11919477979462598 * G + 0.9505321522496607 * B local L, C, h if (Y > 0.00885645167903563082) then L = 116 * math.pow(Y, 1/3) - 16 else L = Y * 903.2962962962962962963 end if ((r == g and g == b) or L == 0) then C = 0 h = 0 else d = X + 3 * Z + 15 * Y if (d == 0) then C = 0 h = 0 else -- 0.19783... and 0.4631... computed with extra precision from (X,Y,Z) when (R,G,B) = (1,1,1), -- in which case (u,v) ≈ (0,0) local us = 4 * X / d - 0.19783000664283678994 local vs = 9 * Y / d - 0.46831999493879099801 h = math.atan2(vs, us) * 57.2957795130823208768 if (h < 0) then h = h + 360 elseif (h == 0) then h = 0 -- ensure zero is positive end C = math.sqrt(us * us + vs * vs) * 13 * L if (C == 0) then C = 0 h = 0 end end end return { L = L, C = C, h = h } end local function srgbMix(t, r0, g0, b0, r1, g1, b1) if (t > 1 or t < 0) then error("Interpolation parameter out of bounds") end if (r0 > 255 or g0 > 255 or b0 > 255 or r1 > 255 or g1 > 255 or b1 > 255 or r0 < 0 or g0 < 0 or b0 < 0 or r1 < 0 or g1 < 0 or b1 < 0) then error("Color level out of bounds") end local tc = 1 - t return { r = toNonLinear(tc * toLinear(r0) + t * toLinear(r1)), g = toNonLinear(tc * toLinear(g0) + t * toLinear(g1)), b = toNonLinear(tc * toLinear(b0) + t * toLinear(b1)) } end local function formatToPrecision(value, p) return string.format("%." .. p .. "f", value) end local function getFractionalZeros(p) if (p > 0) then return "." .. string.rep("0", p) else return "" end end function p.hexToRgbTriplet(frame) local args = frame.args or frame:getParent().args local hex = args[1] if (hex) then local rgb = hexToRgb(hex) return rgb.r .. ', ' .. rgb.g .. ', ' .. rgb.b else return "" end end function p.rgbTripletToHex(frame) local args = frame.args or frame:getParent().args local r = tonumber(args[1]) local g = tonumber(args[2]) local b = tonumber(args [3]) if (isempty(r) or isempty(g) or isempty(b)) then return "" else return rgbToHex(r,g,b) end end function p.hexToCmyk(frame) local args = frame.args or frame:getParent().args local hex = args[1] if (hex) then local p = tonumber(args.precision) or 0 local s = args.pctsign or "1" local rgb = hexToRgb(hex) local cmyk = rgbToCmyk(rgb.r, rgb.g, rgb.b) local fk = formatToPrecision(cmyk.k, p) local fc, fm, fy local fracZeros = getFractionalZeros(p) if (fk == 100 .. fracZeros) then local fZero = 0 .. fracZeros fc = fZero fm = fZero fy = fZero else fc = formatToPrecision(cmyk.c, p) fm = formatToPrecision(cmyk.m, p) fy = formatToPrecision(cmyk.y, p) end if (s ~= "0") then return fc .. "%, " .. fm .. "%, " .. fy .. "%, " .. fk .. "%" else return fc .. ", " .. fm .. ", " .. fy .. ", " .. fk end else return "" end end function p.hexToHsl(frame) local args = frame.args or frame:getParent().args local hex = args[1] if (hex) then local p = tonumber(args.precision) or 0 local rgb = hexToRgb(hex) local hsl = rgbToHsl(rgb.r, rgb.g, rgb.b) local fl = formatToPrecision(hsl.l, p) local fs, fh local fracZeros = getFractionalZeros(p) local fZero = 0 .. fracZeros if (fl == fZero or fl == 100 .. fracZeros) then fs = fZero fh = fZero else fs = formatToPrecision(hsl.s, p) if (fs == fZero) then fh = fZero else fh = formatToPrecision(hsl.h, p) if (fh == 360 .. fracZeros) then fh = fZero -- handle rounding to 360 end end end return fh .. "°, " .. fs .. "%, " .. fl .. "%" else return "" end end function p.hexToHsv(frame) local args = frame.args or frame:getParent().args local hex = args[1] if (hex) then local p = tonumber(args.precision) or 0 local rgb = hexToRgb(hex) local hsv = rgbToHsv(rgb.r, rgb.g, rgb.b) local fv = formatToPrecision(hsv.v, p) local fs, fh local fracZeros = getFractionalZeros(p) local fZero = 0 .. fracZeros if (fv == fZero) then fh = fZero fs = fZero else fs = formatToPrecision(hsv.s, p) if (fs == fZero) then fh = fZero else fh = formatToPrecision(hsv.h, p) if (fh == 360 .. fracZeros) then fh = fZero -- handle rounding to 360 end end end return fh .. "°, " .. fs .. "%, " .. fv .. "%" else return "" end end function p.hexToCielch(frame) local args = frame.args or frame:getParent().args local hex = args[1] if (hex) then local p = tonumber(args.precision) or 0 local rgb = hexToRgb(hex) local LCh = srgbToCielchuvD65o2deg(rgb.r, rgb.g, rgb.b) local fL = formatToPrecision(LCh.L, p) local fC, fh local fracZeros = getFractionalZeros(p) local fZero = 0 .. fracZeros if (fL == fZero or fL == 100 .. fracZeros) then fC = fZero fh = fZero else fC = formatToPrecision(LCh.C, p) if (fC == fZero) then fh = fZero else fh = formatToPrecision(LCh.h, p) if (fh == 360 .. fracZeros) then fh = fZero -- handle rounding to 360 end end end return fL .. ", " .. fC .. ", " .. fh .. "°" else return "" end end function p.hexMix(frame) local args = frame.args or frame:getParent().args local hex0 = args[1] local hex1 = args[2] if (isempty(hex0) or isempty(hex1)) then return "" end local t = args[3] if (isempty(t)) then t = 0.5 else t = tonumber(t) local min = tonumber(args.min) or 0 local max = tonumber(args.max) or 100 if (min >= max) then error("Minimum proportion greater than or equal to maximum") elseif (t < min) then t = 0 elseif (t > max) then t = 1 else t = (t - min) / (max - min) end end local rgb0 = hexToRgb(hex0) local rgb1 = hexToRgb(hex1) local rgb = srgbMix(t, rgb0.r, rgb0.g, rgb0.b, rgb1.r, rgb1.g, rgb1.b) return rgbToHex(rgb.r, rgb.g, rgb.b) end return p eb96d4d42bef9082ca3d2b1ce6b058a590b14494 158 157 2023-10-05T16:52:36Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Color]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- Introduction: https://colorspace.r-forge.r-project.org/articles/color_spaces.html local p = {} local function isempty(v) return v == nil or v == '' end local function hexToRgb(color) local cleanColor = color:gsub("&#35;", "#"):match('^[%s#]*(.-)[%s;]*$') if (#cleanColor == 6) then return { r = tonumber(string.sub(cleanColor, 1, 2), 16), g = tonumber(string.sub(cleanColor, 3, 4), 16), b = tonumber(string.sub(cleanColor, 5, 6), 16) } elseif (#cleanColor == 3) then return { r = 17 * tonumber(string.sub(cleanColor, 1, 1), 16), g = 17 * tonumber(string.sub(cleanColor, 2, 2), 16), b = 17 * tonumber(string.sub(cleanColor, 3, 3), 16) } end error("Invalid hexadecimal color " .. cleanColor, 1) end local function round(v) if (v < 0) then return math.ceil(v - 0.5) else return math.floor(v + 0.5) end end local function rgbToHex(r, g, b) return string.format("%02X%02X%02X", round(r), round(g), round(b)) end local function rgbToCmyk(r, g, b) if (r > 255 or g > 255 or b > 255 or r < 0 or g < 0 or b < 0) then error("Color level out of bounds") end local c = 1 - r / 255 local m = 1 - g / 255 local y = 1 - b / 255 local k = math.min(c, m, y) if (k == 1) then c = 0 m = 0 y = 0 else local d = 1 - k c = (c - k) / d m = (m - k) / d y = (y - k) / d end return { c = c * 100, m = m * 100, y = y * 100, k = k * 100 } end local function rgbToHsl(r, g, b) if (r > 255 or g > 255 or b > 255 or r < 0 or g < 0 or b < 0) then error("Color level out of bounds") end local channelMax = math.max(r, g, b) local channelMin = math.min(r, g, b) local range = channelMax - channelMin local h, s if (range == 0) then h = 0 elseif (channelMax == r) then h = 60 * ((g - b) / range) if (h < 0) then h = 360 + h end elseif (channelMax == g) then h = 60 * (2 + (b - r) / range) else h = 60 * (4 + (r - g) / range) end local L = channelMax + channelMin if (L == 0 or L == 510) then s = 0 else s = 100 * range / math.min(L, 510 - L) end return { h = h, s = s, l = L * 50 / 255 } end local function rgbToHsv(r, g, b) if (r > 255 or g > 255 or b > 255 or r < 0 or g < 0 or b < 0) then error("Color level out of bounds") end local channelMax = math.max(r, g, b) local channelMin = math.min(r, g, b) local range = channelMax - channelMin local h, s if (range == 0) then h = 0 elseif (channelMax == r) then h = 60 * ((g - b) / range) if (h < 0) then h = 360 + h end elseif (channelMax == g) then h = 60 * (2 + (b - r) / range) else h = 60 * (4 + (r - g) / range) end if (channelMax == 0) then s = 0 else s = 100 * range / channelMax end return { h = h, s = s, v = channelMax * 100 / 255 } end -- c in [0, 255], condition tweaked for no discontinuity -- http://entropymine.com/imageworsener/srgbformula/ local function toLinear(c) if (c > 10.314300250662591) then return math.pow((c + 14.025) / 269.025, 2.4) else return c / 3294.6 end end local function toNonLinear(c) if (c > 0.00313066844250063) then return 269.025 * math.pow(c, 1.0/2.4) - 14.025 else return 3294.6 * c end end local function srgbToCielchuvD65o2deg(r, g, b) if (r > 255 or g > 255 or b > 255 or r < 0 or g < 0 or b < 0) then error("Color level out of bounds") end local R = toLinear(r) local G = toLinear(g) local B = toLinear(b) -- https://github.com/w3c/csswg-drafts/issues/5922 local X = 0.1804807884018343 * B + 0.357584339383878 * G + 0.41239079926595934 * R local Y = 0.07219231536073371 * B + 0.21263900587151027 * R + 0.715168678767756 * G local Z = 0.01933081871559182 * R + 0.11919477979462598 * G + 0.9505321522496607 * B local L, C, h if (Y > 0.00885645167903563082) then L = 116 * math.pow(Y, 1/3) - 16 else L = Y * 903.2962962962962962963 end if ((r == g and g == b) or L == 0) then C = 0 h = 0 else d = X + 3 * Z + 15 * Y if (d == 0) then C = 0 h = 0 else -- 0.19783... and 0.4631... computed with extra precision from (X,Y,Z) when (R,G,B) = (1,1,1), -- in which case (u,v) ≈ (0,0) local us = 4 * X / d - 0.19783000664283678994 local vs = 9 * Y / d - 0.46831999493879099801 h = math.atan2(vs, us) * 57.2957795130823208768 if (h < 0) then h = h + 360 elseif (h == 0) then h = 0 -- ensure zero is positive end C = math.sqrt(us * us + vs * vs) * 13 * L if (C == 0) then C = 0 h = 0 end end end return { L = L, C = C, h = h } end local function srgbMix(t, r0, g0, b0, r1, g1, b1) if (t > 1 or t < 0) then error("Interpolation parameter out of bounds") end if (r0 > 255 or g0 > 255 or b0 > 255 or r1 > 255 or g1 > 255 or b1 > 255 or r0 < 0 or g0 < 0 or b0 < 0 or r1 < 0 or g1 < 0 or b1 < 0) then error("Color level out of bounds") end local tc = 1 - t return { r = toNonLinear(tc * toLinear(r0) + t * toLinear(r1)), g = toNonLinear(tc * toLinear(g0) + t * toLinear(g1)), b = toNonLinear(tc * toLinear(b0) + t * toLinear(b1)) } end local function formatToPrecision(value, p) return string.format("%." .. p .. "f", value) end local function getFractionalZeros(p) if (p > 0) then return "." .. string.rep("0", p) else return "" end end function p.hexToRgbTriplet(frame) local args = frame.args or frame:getParent().args local hex = args[1] if (hex) then local rgb = hexToRgb(hex) return rgb.r .. ', ' .. rgb.g .. ', ' .. rgb.b else return "" end end function p.rgbTripletToHex(frame) local args = frame.args or frame:getParent().args local r = tonumber(args[1]) local g = tonumber(args[2]) local b = tonumber(args [3]) if (isempty(r) or isempty(g) or isempty(b)) then return "" else return rgbToHex(r,g,b) end end function p.hexToCmyk(frame) local args = frame.args or frame:getParent().args local hex = args[1] if (hex) then local p = tonumber(args.precision) or 0 local s = args.pctsign or "1" local rgb = hexToRgb(hex) local cmyk = rgbToCmyk(rgb.r, rgb.g, rgb.b) local fk = formatToPrecision(cmyk.k, p) local fc, fm, fy local fracZeros = getFractionalZeros(p) if (fk == 100 .. fracZeros) then local fZero = 0 .. fracZeros fc = fZero fm = fZero fy = fZero else fc = formatToPrecision(cmyk.c, p) fm = formatToPrecision(cmyk.m, p) fy = formatToPrecision(cmyk.y, p) end if (s ~= "0") then return fc .. "%, " .. fm .. "%, " .. fy .. "%, " .. fk .. "%" else return fc .. ", " .. fm .. ", " .. fy .. ", " .. fk end else return "" end end function p.hexToHsl(frame) local args = frame.args or frame:getParent().args local hex = args[1] if (hex) then local p = tonumber(args.precision) or 0 local rgb = hexToRgb(hex) local hsl = rgbToHsl(rgb.r, rgb.g, rgb.b) local fl = formatToPrecision(hsl.l, p) local fs, fh local fracZeros = getFractionalZeros(p) local fZero = 0 .. fracZeros if (fl == fZero or fl == 100 .. fracZeros) then fs = fZero fh = fZero else fs = formatToPrecision(hsl.s, p) if (fs == fZero) then fh = fZero else fh = formatToPrecision(hsl.h, p) if (fh == 360 .. fracZeros) then fh = fZero -- handle rounding to 360 end end end return fh .. "°, " .. fs .. "%, " .. fl .. "%" else return "" end end function p.hexToHsv(frame) local args = frame.args or frame:getParent().args local hex = args[1] if (hex) then local p = tonumber(args.precision) or 0 local rgb = hexToRgb(hex) local hsv = rgbToHsv(rgb.r, rgb.g, rgb.b) local fv = formatToPrecision(hsv.v, p) local fs, fh local fracZeros = getFractionalZeros(p) local fZero = 0 .. fracZeros if (fv == fZero) then fh = fZero fs = fZero else fs = formatToPrecision(hsv.s, p) if (fs == fZero) then fh = fZero else fh = formatToPrecision(hsv.h, p) if (fh == 360 .. fracZeros) then fh = fZero -- handle rounding to 360 end end end return fh .. "°, " .. fs .. "%, " .. fv .. "%" else return "" end end function p.hexToCielch(frame) local args = frame.args or frame:getParent().args local hex = args[1] if (hex) then local p = tonumber(args.precision) or 0 local rgb = hexToRgb(hex) local LCh = srgbToCielchuvD65o2deg(rgb.r, rgb.g, rgb.b) local fL = formatToPrecision(LCh.L, p) local fC, fh local fracZeros = getFractionalZeros(p) local fZero = 0 .. fracZeros if (fL == fZero or fL == 100 .. fracZeros) then fC = fZero fh = fZero else fC = formatToPrecision(LCh.C, p) if (fC == fZero) then fh = fZero else fh = formatToPrecision(LCh.h, p) if (fh == 360 .. fracZeros) then fh = fZero -- handle rounding to 360 end end end return fL .. ", " .. fC .. ", " .. fh .. "°" else return "" end end function p.hexMix(frame) local args = frame.args or frame:getParent().args local hex0 = args[1] local hex1 = args[2] if (isempty(hex0) or isempty(hex1)) then return "" end local t = args[3] if (isempty(t)) then t = 0.5 else t = tonumber(t) local min = tonumber(args.min) or 0 local max = tonumber(args.max) or 100 if (min >= max) then error("Minimum proportion greater than or equal to maximum") elseif (t < min) then t = 0 elseif (t > max) then t = 1 else t = (t - min) / (max - min) end end local rgb0 = hexToRgb(hex0) local rgb1 = hexToRgb(hex1) local rgb = srgbMix(t, rgb0.r, rgb0.g, rgb0.b, rgb1.r, rgb1.g, rgb1.b) return rgbToHex(rgb.r, rgb.g, rgb.b) end return p eb96d4d42bef9082ca3d2b1ce6b058a590b14494 มอดูล:HexShade 828 83 159 2023-10-05T16:54:48Z PeachFullzZ 2 สร้างหน้าด้วย "-- This module implements {{HexShade}} local p = {} local function rgbdec2hex(r, g, b, d) if (r >= 0 and g >= 0 and b >= 0 ) then local baseconvert = require('Module:BaseConvert') local s1 = baseconvert.convert({n = math.floor(r+0.5), base = 16}) local s2 = baseconvert.convert({n = math.floor(g+0.5), base = 16}) local s3 = baseconvert.convert({n = math.floor(b+0.5), base = 16}) s1 = mw.ustring.gsub(s1, '^([0-9A-Fa-f])$', '0%1') s2 = mw..." Scribunto text/plain -- This module implements {{HexShade}} local p = {} local function rgbdec2hex(r, g, b, d) if (r >= 0 and g >= 0 and b >= 0 ) then local baseconvert = require('Module:BaseConvert') local s1 = baseconvert.convert({n = math.floor(r+0.5), base = 16}) local s2 = baseconvert.convert({n = math.floor(g+0.5), base = 16}) local s3 = baseconvert.convert({n = math.floor(b+0.5), base = 16}) s1 = mw.ustring.gsub(s1, '^([0-9A-Fa-f])$', '0%1') s2 = mw.ustring.gsub(s2, '^([0-9A-Fa-f])$', '0%1') s3 = mw.ustring.gsub(s3, '^([0-9A-Fa-f])$', '0%1') return (s1 .. s2 .. s3):upper() end return d end local function rgbdec2hsl(r, g, b) local H, S, L local max = math.max(r, g, b) local min = math.min(r, g, b) -- hue if ((r == g) and (g == b)) then H = 0 elseif ((g >= r) and (g >= b)) then if (r > b) then H = 120 - 60 * (r - b) / (g - b) else H = 120 + 60 * (b - r) / (g - r) end elseif ((b >= r) and (b >= g)) then if (g > r) then H = 240 - 60 * (g - r) / (b - r) else H = 240 + 60 * (r - g) / (b - g) end else if (b > g) then H = 360 - 60 * (b - g) / (r - g) else H = 60 * (g - b) / (r - b) end end -- saturation if ((r == g) and (g == b)) then S = 0 else if ((max + min) > 255) then S = (max - min) / (510 - max - min) else S = (max - min) / (max + min) end end -- luminosity L = (max + min) / (255 * 2) return H, S, L end local function hsl2rgbdec(h, s, l) -- This function came from [[Module:Color contrast]] if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then local c = (1 - math.abs(2*l - 1))*s local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) ) local m = l - c/2 local r, g, b = m, m, m if( 0 <= h and h < 60 ) then r = r + c g = g + x elseif( 60 <= h and h < 120 ) then r = r + x g = g + c elseif( 120 <= h and h < 180 ) then g = g + c b = b + x elseif( 180 <= h and h < 240 ) then g = g + x b = b + c elseif( 240 <= h and h < 300 ) then r = r + x b = b + c elseif( 300 <= h and h < 360 ) then r = r + c b = b + x end return 255*r, 255*g, 255*b end return -1, -1, -1 end function p.main(frame) local args = require('Module:Arguments').getArgs(frame) -- Remove nowiki and leading hash signs local c = mw.text.unstrip(args[1] or '#f0e68c') c = mw.ustring.match(c, '^[%s]*(.-)[%s]*$') c = mw.ustring.gsub(c, '^[%s#]*', '') c = mw.ustring.gsub(c, '^&#35;[%s]*', '') -- Lowercase c = c:lower() mw.log(c) -- Expand short 3 hex for to 6 hex form c = mw.ustring.gsub(c, '^([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])$', '%1%1%2%2%3%3') mw.log(c) -- Get new value for luminosity local Lnew = tonumber(args[2] or '-1') or 0.6 -- Default return local res = c -- Adjust shading local cs = mw.text.split(c or '', '') if( #cs == 6 ) then -- Convert to RGBdec local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2]) local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4]) local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6]) mw.log(R, G, B) -- Convert RGBdec to HSL local H, S, L = rgbdec2hsl(R, G, B) mw.log(H, S, L) -- Convert back to RGBdec local R, G, B = hsl2rgbdec(H, S, Lnew) -- Convert back to RGBhex res = rgbdec2hex(R, G, B, c) end res = res:upper() if args[3] == '#' and mw.ustring.match(res, '^[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]$') then return '#' .. res end return res end return p b4bff4ee440c93876d5afc9a8363d757666b0888 160 159 2023-10-05T16:55:05Z PeachFullzZ 2 ป้องกัน "[[มอดูล:HexShade]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- This module implements {{HexShade}} local p = {} local function rgbdec2hex(r, g, b, d) if (r >= 0 and g >= 0 and b >= 0 ) then local baseconvert = require('Module:BaseConvert') local s1 = baseconvert.convert({n = math.floor(r+0.5), base = 16}) local s2 = baseconvert.convert({n = math.floor(g+0.5), base = 16}) local s3 = baseconvert.convert({n = math.floor(b+0.5), base = 16}) s1 = mw.ustring.gsub(s1, '^([0-9A-Fa-f])$', '0%1') s2 = mw.ustring.gsub(s2, '^([0-9A-Fa-f])$', '0%1') s3 = mw.ustring.gsub(s3, '^([0-9A-Fa-f])$', '0%1') return (s1 .. s2 .. s3):upper() end return d end local function rgbdec2hsl(r, g, b) local H, S, L local max = math.max(r, g, b) local min = math.min(r, g, b) -- hue if ((r == g) and (g == b)) then H = 0 elseif ((g >= r) and (g >= b)) then if (r > b) then H = 120 - 60 * (r - b) / (g - b) else H = 120 + 60 * (b - r) / (g - r) end elseif ((b >= r) and (b >= g)) then if (g > r) then H = 240 - 60 * (g - r) / (b - r) else H = 240 + 60 * (r - g) / (b - g) end else if (b > g) then H = 360 - 60 * (b - g) / (r - g) else H = 60 * (g - b) / (r - b) end end -- saturation if ((r == g) and (g == b)) then S = 0 else if ((max + min) > 255) then S = (max - min) / (510 - max - min) else S = (max - min) / (max + min) end end -- luminosity L = (max + min) / (255 * 2) return H, S, L end local function hsl2rgbdec(h, s, l) -- This function came from [[Module:Color contrast]] if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then local c = (1 - math.abs(2*l - 1))*s local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) ) local m = l - c/2 local r, g, b = m, m, m if( 0 <= h and h < 60 ) then r = r + c g = g + x elseif( 60 <= h and h < 120 ) then r = r + x g = g + c elseif( 120 <= h and h < 180 ) then g = g + c b = b + x elseif( 180 <= h and h < 240 ) then g = g + x b = b + c elseif( 240 <= h and h < 300 ) then r = r + x b = b + c elseif( 300 <= h and h < 360 ) then r = r + c b = b + x end return 255*r, 255*g, 255*b end return -1, -1, -1 end function p.main(frame) local args = require('Module:Arguments').getArgs(frame) -- Remove nowiki and leading hash signs local c = mw.text.unstrip(args[1] or '#f0e68c') c = mw.ustring.match(c, '^[%s]*(.-)[%s]*$') c = mw.ustring.gsub(c, '^[%s#]*', '') c = mw.ustring.gsub(c, '^&#35;[%s]*', '') -- Lowercase c = c:lower() mw.log(c) -- Expand short 3 hex for to 6 hex form c = mw.ustring.gsub(c, '^([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])$', '%1%1%2%2%3%3') mw.log(c) -- Get new value for luminosity local Lnew = tonumber(args[2] or '-1') or 0.6 -- Default return local res = c -- Adjust shading local cs = mw.text.split(c or '', '') if( #cs == 6 ) then -- Convert to RGBdec local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2]) local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4]) local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6]) mw.log(R, G, B) -- Convert RGBdec to HSL local H, S, L = rgbdec2hsl(R, G, B) mw.log(H, S, L) -- Convert back to RGBdec local R, G, B = hsl2rgbdec(H, S, Lnew) -- Convert back to RGBhex res = rgbdec2hex(R, G, B, c) end res = res:upper() if args[3] == '#' and mw.ustring.match(res, '^[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]$') then return '#' .. res end return res end return p b4bff4ee440c93876d5afc9a8363d757666b0888 สภานิติบัญญัติแห่งชาติ พ.ศ. 2566 0 68 161 151 2023-10-05T16:55:19Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ | name = สภานิติบัญญัติแห่งชาติ | coa_pic = | coa_res = | session_room = | session_res = | house_type = ระบบสภาเดียว | houses = | leader1_type = [[ประธานสภานิติบัญญัติแห่งชาติ|ประธาน]] | leader1 = [[เนติวิทย์ นวโชติ]] | party1 = | election1 = | leader2_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 1]] | leader2 = [[โฆษิต นวชาติ]] | party2 = | election2 = | leader3_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 2]] | leader3 = [[ณิชานันท์ ธนินทวรานนท์]] | party3 = | election3 = | members = 39 ที่นั่ง |structure1 = National Legislative Assembly of Thailand (2023).svg |structure1_res = 270px | house1 = | house2 = | political_groups1 = ได้รับการแต่งตั้งมาจากภาคส่วนต่าง ๆ<br />{{colorbox|#53639B}} [[บริษัท วานิเฉียนกรุป จำกัด]] (10)<br /> {{colorbox|#964B00}} [[พรรคสมัยใหม่]] (8)<br /> {{colorbox|#FF0000}} [[นักการเมืองอิสระ|อิสระ]] (7)<br /> {{colorbox|#808080}} [[ข้าราชการ]] (6)<br /> {{colorbox|#808080}} [[พรรคประชาธิปัตย์]] (1)<br /> {{colorbox|#808080}} [[แพทย์]] (1) | political_groups2 = | last_election1 = | next_election2 = | meeting_place = [[สัปปายะสภาสถาน]] [[เขตดุสิต]] [[กรุงเทพมหานคร]] [[ประเทศไทย]] | website = {{URL|https://discord.gg/ZeBQkrchEP}} }} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564]] == รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ == {| class="wikitable sortable" |- ! colspan=2 | กลุ่มรัฐสภา ! ชื่อ-นามสกุล ! อาชีพ ! หมายเหตุ |- | | กลุ่มแพทย์ | ขะเหมียว ธาราวัชรจินดา | ผู้อำนวยการ[[โรงพยาบาลจุฬาลงกรณ์ สภากาชาดไทย]] | |- | | กลุ่มอิสระ | คิเอะ เสาร์แก้ว | คอนเทนต์ครีเอเตอร์ | |- | | กลุ่มนักการเมือง | โฆษิต นวชาติ | อดีตประธานรัฐสภา และนักการเมือง | รองประธานสภาคนที่ 1 |- | | กลุ่มข้าราชการ | จรดล แซ่เหงียน | อธิบดี[[กรมศิลปากร]] | |- | | กลุ่มนักการเมือง | อานุภาพ คุณูปจางบริรักษ์ | นายกรัฐมนตรี และหัวหน้า[[พรรคประชาธิปัตย์]] | |- |} 211de6a20cb97b632fc77d40458107c808762499 162 161 2023-10-05T17:00:41Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ | name = สภานิติบัญญัติแห่งชาติ | coa_pic = | coa_res = | session_room = | session_res = | house_type = ระบบสภาเดียว | houses = | leader1_type = [[ประธานสภานิติบัญญัติแห่งชาติ|ประธาน]] | leader1 = [[เนติวิทย์ นวโชติ]] | party1 = | election1 = | leader2_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 1]] | leader2 = [[โฆษิต นวชาติ]] | party2 = | election2 = | leader3_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 2]] | leader3 = [[ณิชานันท์ ธนินทวรานนท์]] | party3 = | election3 = | members = 39 ที่นั่ง |structure1 = National Legislative Assembly of Thailand (2023).svg |structure1_res = 270px | house1 = | house2 = | political_groups1 = ได้รับการแต่งตั้งมาจากภาคส่วนต่าง ๆ<br />{{colorbox|#53639B}} [[บริษัท วานิเฉียนกรุป จำกัด]] (10)<br /> {{colorbox|#96E200}} [[พรรคสมัยใหม่]] (8)<br /> {{colorbox|#DBDBDB}} อิสระ (7)<br /> {{colorbox|#C8AC7E}} [[ข้าราชการ]] (6)<br /> {{colorbox|#CC2F29}} [[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] (5)<br />{{colorbox|#2ECC71}} [[แพทย์]] (2)<br /> {{colorbox|#008BD0}} [[พรรคประชาธิปัตย์]] (1)<br /> {{colorbox|#1A5CCC}} [[นักการเมืองอิสระ]] (1) | political_groups2 = | last_election1 = | next_election2 = | meeting_place = [[สัปปายะสภาสถาน]] [[เขตดุสิต]] [[กรุงเทพมหานคร]] [[ประเทศไทย]] | website = {{URL|https://discord.gg/ZeBQkrchEP}} }} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564]] == รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ == {| class="wikitable sortable" |- ! colspan=2 | กลุ่มรัฐสภา ! ชื่อ-นามสกุล ! อาชีพ ! หมายเหตุ |- | | กลุ่มแพทย์ | ขะเหมียว ธาราวัชรจินดา | ผู้อำนวยการ[[โรงพยาบาลจุฬาลงกรณ์ สภากาชาดไทย]] | |- | | กลุ่มอิสระ | คิเอะ เสาร์แก้ว | คอนเทนต์ครีเอเตอร์ | |- | | กลุ่มนักการเมือง | โฆษิต นวชาติ | อดีตประธานรัฐสภา และนักการเมือง | รองประธานสภาคนที่ 1 |- | | กลุ่มข้าราชการ | จรดล แซ่เหงียน | อธิบดี[[กรมศิลปากร]] | |- | | กลุ่มนักการเมือง | อานุภาพ คุณูปจางบริรักษ์ | นายกรัฐมนตรี และหัวหน้า[[พรรคประชาธิปัตย์]] | |- |} 9b2071111a23796f3df8c90bb76b187f6f754de1 171 162 2023-10-05T19:05:40Z PeachFullzZ 2 /* รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ */ wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ | name = สภานิติบัญญัติแห่งชาติ | coa_pic = | coa_res = | session_room = | session_res = | house_type = ระบบสภาเดียว | houses = | leader1_type = [[ประธานสภานิติบัญญัติแห่งชาติ|ประธาน]] | leader1 = [[เนติวิทย์ นวโชติ]] | party1 = | election1 = | leader2_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 1]] | leader2 = [[โฆษิต นวชาติ]] | party2 = | election2 = | leader3_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 2]] | leader3 = [[ณิชานันท์ ธนินทวรานนท์]] | party3 = | election3 = | members = 39 ที่นั่ง |structure1 = National Legislative Assembly of Thailand (2023).svg |structure1_res = 270px | house1 = | house2 = | political_groups1 = ได้รับการแต่งตั้งมาจากภาคส่วนต่าง ๆ<br />{{colorbox|#53639B}} [[บริษัท วานิเฉียนกรุป จำกัด]] (10)<br /> {{colorbox|#96E200}} [[พรรคสมัยใหม่]] (8)<br /> {{colorbox|#DBDBDB}} อิสระ (7)<br /> {{colorbox|#C8AC7E}} [[ข้าราชการ]] (6)<br /> {{colorbox|#CC2F29}} [[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] (5)<br />{{colorbox|#2ECC71}} [[แพทย์]] (2)<br /> {{colorbox|#008BD0}} [[พรรคประชาธิปัตย์]] (1)<br /> {{colorbox|#1A5CCC}} [[นักการเมืองอิสระ]] (1) | political_groups2 = | last_election1 = | next_election2 = | meeting_place = [[สัปปายะสภาสถาน]] [[เขตดุสิต]] [[กรุงเทพมหานคร]] [[ประเทศไทย]] | website = {{URL|https://discord.gg/ZeBQkrchEP}} }} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564]] == รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ == {| class="wikitable sortable" |- ! colspan=2 | กลุ่มการเมือง ! ชื่อ-นามสกุล ! อาชีพ ! หมายเหตุ |- | bgcolor = "#2ECC71"| | กลุ่มแพทย์ | ขะเหมียว ธาราวัชรจินดา | ผู้อำนวยการ[[โรงพยาบาลจุฬาลงกรณ์ สภากาชาดไทย]] | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | คิเอะ เสาร์แก้ว | คอนเทนต์ครีเอเตอร์ | |- | bgcolor = "#1A5CCC"| | กลุ่มนักการเมือง (อิสระ) | โฆษิต นวชาติ | อดีตประธานรัฐสภา และนักการเมือง | รองประธานสภาคนที่ 1 |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จรดล แซ่เหงียน | อธิบดี[[กรมศิลปากร]] | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | เนติวิทย์ นวโชติ | อดีตพระประมุข และประธานศาลฎีกา | ประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | [[อนาวิน สุขเกษมอดิศักดิ์]] | อดีตตุลาการศาลรัฐธรรมนูญ อดีตหัวหน้าและสมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (บริษัท วานิเฉียนกรุป จำกัด) | อเดลเบิร์ต เฉียน | ประธานกรรมการบริษัท วานิเฉียนกรุป จำกัด |- | bgcolor = "#008BD0"| | กลุ่มนักการเมือง (พรรคประชาธิปัตย์) | อานุภาพ คุณูปจางบริรักษ์ | นายกรัฐมนตรี และหัวหน้า[[พรรคประชาธิปัตย์]] | |- |} 5b069612a852faad8b6370eb93405070a345dcde 172 171 2023-10-05T19:36:28Z PeachFullzZ 2 /* รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ */ wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ | name = สภานิติบัญญัติแห่งชาติ | coa_pic = | coa_res = | session_room = | session_res = | house_type = ระบบสภาเดียว | houses = | leader1_type = [[ประธานสภานิติบัญญัติแห่งชาติ|ประธาน]] | leader1 = [[เนติวิทย์ นวโชติ]] | party1 = | election1 = | leader2_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 1]] | leader2 = [[โฆษิต นวชาติ]] | party2 = | election2 = | leader3_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 2]] | leader3 = [[ณิชานันท์ ธนินทวรานนท์]] | party3 = | election3 = | members = 39 ที่นั่ง |structure1 = National Legislative Assembly of Thailand (2023).svg |structure1_res = 270px | house1 = | house2 = | political_groups1 = ได้รับการแต่งตั้งมาจากภาคส่วนต่าง ๆ<br />{{colorbox|#53639B}} [[บริษัท วานิเฉียนกรุป จำกัด]] (10)<br /> {{colorbox|#96E200}} [[พรรคสมัยใหม่]] (8)<br /> {{colorbox|#DBDBDB}} อิสระ (7)<br /> {{colorbox|#C8AC7E}} [[ข้าราชการ]] (6)<br /> {{colorbox|#CC2F29}} [[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] (5)<br />{{colorbox|#2ECC71}} [[แพทย์]] (2)<br /> {{colorbox|#008BD0}} [[พรรคประชาธิปัตย์]] (1)<br /> {{colorbox|#1A5CCC}} [[นักการเมืองอิสระ]] (1) | political_groups2 = | last_election1 = | next_election2 = | meeting_place = [[สัปปายะสภาสถาน]] [[เขตดุสิต]] [[กรุงเทพมหานคร]] [[ประเทศไทย]] | website = {{URL|https://discord.gg/ZeBQkrchEP}} }} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564]] == รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ == {| class="wikitable sortable" |- ! colspan=2 | กลุ่มการเมือง ! ชื่อ-นามสกุล ! อาชีพ ! หมายเหตุ |- | bgcolor = "#2ECC71"| | กลุ่มแพทย์ | ขะเหมียว ธาราวัชรจินดา | ผู้อำนวยการ[[โรงพยาบาลจุฬาลงกรณ์ สภากาชาดไทย]] | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | คิเอะ เสาร์แก้ว | คอนเทนต์ครีเอเตอร์ | |- | bgcolor = "#1A5CCC"| | กลุ่มนักการเมือง (อิสระ) | โฆษิต นวชาติ | อดีตประธานรัฐสภา และนักการเมือง | รองประธานสภาคนที่ 1 |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จรดล แซ่เหงียน | อธิบดี[[กรมศิลปากร]] | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จักรภพ เทเวศร์โยธิน | | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | จิน เดอฌอง ดูว์ วาณิช | ประธานเจ้าหน้าที่บริหารบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จิราติ ศักดา | เจ้าหน้าที่งานในพระประมุข | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | จุทาเทพยศะมหรนะ ธาราวัชรจินดา | รองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ซาลาห์ เออร์บาโน่ ดูว์ วาณิช | กรรมการอิสระบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ซีวาน ดูว์ วาณิช | รองประธานกรรมการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | ณิชานันท์ ธนินทวรานนท์ | เลขาธิการพรรคสมัยใหม่ | รองประธานสภาคนที่ 2 |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | แดนนีลีน เฉียน | ประธานเจ้าหน้าที่การเงินบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#2ECC71"| | กลุ่มแพทย์ | ธนวุฒิศ์นากิศา ภัทรเวชยสถิต | อดีตประธานประมุขมนตรี | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | ธัณย์สิตา ธาราวัชรจินดา | พระมุขยวงศ์ และรองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | นลิน ศิริธนจริยานนท์ | กรรมการบริหารพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | นาถสุรีย์วิภา อรปรียา | สมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | นาธานาเอล ชาลส์ ดูว์ วาณิช | ประธานเจ้าหน้าที่เทคโนโลยีบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | เนติวิทย์ นวโชติ | อดีตพระประมุข และประธานศาลฎีกา | ประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | โนอา คอร์แยน ดูว์ วาณิช | ประธานเจ้าหน้าที่ปฏิบัติการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | บิลลีอัลมานี ธาราวัชรจินดา | รองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | เบญจา วรรณศิริลักษณ์ | กรรมการบริหารพรรคสมัยใหม่ | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | ภฑิล ชัยทรัพย์มั่นคง | | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | ภูติเดช ธาราวัชรจินดา | กรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | มงคลชาย แสงทวี | โฆษกพรรคสมัยใหม่ | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | วสันต์ อุสมาน หมักคา | | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | วอลเตอร์ ธาราวัชรจินดา | ประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วารีทัศน์ ไวต์ | รองหัวหน้าพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วิทยาภรณ์ อารียไพศาล | รองหัวหน้าพรรคสมัยใหม่ | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | ศักดิ์สยาม ศิลปไชย | เจ้าพนักงานธุรการปฏิบัติงาน [[กระทรวงการต่างประเทศ]] | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ศิริเนตรดารณี ปรียาพัชรวิลาศ วินิจเมธา | กรรมการที่ไม่เป็นผู้บริหารบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | สกธินชารินทร์พธา นวชาติ | | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | สรายุทธ โครตอตร | หัวหน้าพรรคสมัยใหม่ และอดีตอนุญาโตตุลาการ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | สิฟริตต์ เฉียน | | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | [[อนาวิน สุขเกษมอดิศักดิ์]] | อดีตตุลาการศาลรัฐธรรมนูญ อดีตหัวหน้าและสมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | อเดลเบิร์ต เฉียน | ประธานกรรมการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#008BD0"| | กลุ่มนักการเมือง (พรรคประชาธิปัตย์) | อานุภาพ คุณูปจางบริรักษ์ | นายกรัฐมนตรี และหัวหน้าพรรคประชาธิปัตย์ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | เอสดราส โนบิลิส ดูว์ วาณิช | ประธานเจ้าหน้าที่สารสนเทศบริษัท วานิเฉียนกรุป จำกัด | |- |} 2f5d3f98909822def0872c6cb8e5ae1a6bab0ad5 173 172 2023-10-05T19:41:42Z PeachFullzZ 2 /* รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ */ wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ | name = สภานิติบัญญัติแห่งชาติ | coa_pic = | coa_res = | session_room = | session_res = | house_type = ระบบสภาเดียว | houses = | leader1_type = [[ประธานสภานิติบัญญัติแห่งชาติ|ประธาน]] | leader1 = [[เนติวิทย์ นวโชติ]] | party1 = | election1 = | leader2_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 1]] | leader2 = [[โฆษิต นวชาติ]] | party2 = | election2 = | leader3_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 2]] | leader3 = [[ณิชานันท์ ธนินทวรานนท์]] | party3 = | election3 = | members = 39 ที่นั่ง |structure1 = National Legislative Assembly of Thailand (2023).svg |structure1_res = 270px | house1 = | house2 = | political_groups1 = ได้รับการแต่งตั้งมาจากภาคส่วนต่าง ๆ<br />{{colorbox|#53639B}} [[บริษัท วานิเฉียนกรุป จำกัด]] (10)<br /> {{colorbox|#96E200}} [[พรรคสมัยใหม่]] (8)<br /> {{colorbox|#DBDBDB}} อิสระ (7)<br /> {{colorbox|#C8AC7E}} [[ข้าราชการ]] (6)<br /> {{colorbox|#CC2F29}} [[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] (5)<br />{{colorbox|#2ECC71}} [[แพทย์]] (2)<br /> {{colorbox|#008BD0}} [[พรรคประชาธิปัตย์]] (1)<br /> {{colorbox|#1A5CCC}} [[นักการเมืองอิสระ]] (1) | political_groups2 = | last_election1 = | next_election2 = | meeting_place = [[สัปปายะสภาสถาน]] [[เขตดุสิต]] [[กรุงเทพมหานคร]] [[ประเทศไทย]] | website = {{URL|https://discord.gg/ZeBQkrchEP}} }} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564]] == รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ == {| class="wikitable sortable" |- ! colspan=2 | กลุ่มการเมือง ! ชื่อ-นามสกุล ! อาชีพ ! หมายเหตุ |- | bgcolor = "#2ECC71"| | กลุ่มแพทย์ | ขะเหมียว ธาราวัชรจินดา | ผู้อำนวยการ[[โรงพยาบาลจุฬาลงกรณ์ สภากาชาดไทย]] | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | คิเอะ เสาร์แก้ว | คอนเทนต์ครีเอเตอร์ | |- | bgcolor = "#1A5CCC"| | กลุ่มนักการเมือง (อิสระ) | โฆษิต นวชาติ | อดีตประธานรัฐสภา และนักการเมือง | รองประธานสภาคนที่ 1 |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จรดล แซ่เหงียน | อธิบดี[[กรมศิลปากร]] | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จักรภพ เทเวศร์โยธิน | | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | จิน เดอฌอง ดูว์ วาณิช | ประธานเจ้าหน้าที่บริหารบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จิราติ ศักดา | เจ้าหน้าที่งานในพระประมุข | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | จุทาเทพยศะมหรนะ ธาราวัชรจินดา | รองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ซาลาห์ เออร์บาโน่ ดูว์ วาณิช | กรรมการอิสระบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ซีวาน ดูว์ วาณิช | รองประธานกรรมการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | ณิชานันท์ ธนินทวรานนท์ | เลขาธิการพรรคสมัยใหม่ | รองประธานสภาคนที่ 2 |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | แดนนีลีน เฉียน | ประธานเจ้าหน้าที่การเงินบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#2ECC71"| | กลุ่มแพทย์ | ธนวุฒิศ์นากิศา ภัทรเวชยสถิต | อดีตประธานประมุขมนตรี | ที่ปรึกษาประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | ธัณย์สิตา ธาราวัชรจินดา | พระมุขยวงศ์ และรองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | นลิน ศิริธนจริยานนท์ | กรรมการบริหารพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | นาถสุรีย์วิภา อรปรียา | สมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | นาธานาเอล ชาลส์ ดูว์ วาณิช | ประธานเจ้าหน้าที่เทคโนโลยีบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | เนติวิทย์ นวโชติ | อดีตพระประมุข และประธานศาลฎีกา | ประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | โนอา คอร์แยน ดูว์ วาณิช | ประธานเจ้าหน้าที่ปฏิบัติการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | บิลลีอัลมานี ธาราวัชรจินดา | รองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | เบญจา วรรณศิริลักษณ์ | กรรมการบริหารพรรคสมัยใหม่ | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | ภฑิล ชัยทรัพย์มั่นคง | | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | ภูติเดช ธาราวัชรจินดา | กรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | มงคลชาย แสงทวี | โฆษกพรรคสมัยใหม่ | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | รรรรรร ผิดหวัง | | เลขานุการประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | วสันต์ อุสมาน หมักคา | | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | วอลเตอร์ ธาราวัชรจินดา | ประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วารีทัศน์ ไวต์ | รองหัวหน้าพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วิทยาภรณ์ อารียไพศาล | รองหัวหน้าพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วีรยุทธ วัลพัฒวาณิช | สมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | ศักดิ์สยาม ศิลปไชย | เจ้าพนักงานธุรการปฏิบัติงาน [[กระทรวงการต่างประเทศ]] | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ศิริเนตรดารณี ปรียาพัชรวิลาศ วินิจเมธา | กรรมการที่ไม่เป็นผู้บริหารบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | ศุภวิชญ์ พึ่งพารักษ์ | | โฆษกประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | สกธินชารินทร์พธา นวชาติ | | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | สรายุทธ โครตอตร | หัวหน้าพรรคสมัยใหม่ และอดีตอนุญาโตตุลาการ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | สิฟริตต์ เฉียน | | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | [[อนาวิน สุขเกษมอดิศักดิ์]] | อดีตตุลาการศาลรัฐธรรมนูญ อดีตหัวหน้าและสมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | อเดลเบิร์ต เฉียน | ประธานกรรมการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#008BD0"| | กลุ่มนักการเมือง (พรรคประชาธิปัตย์) | อานุภาพ คุณูปจางบริรักษ์ | นายกรัฐมนตรี และหัวหน้าพรรคประชาธิปัตย์ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | เอสดราส โนบิลิส ดูว์ วาณิช | ประธานเจ้าหน้าที่สารสนเทศบริษัท วานิเฉียนกรุป จำกัด | |- |} 1bdd707fc72971c901d42cbecc2992fa357b2f1d 174 173 2023-10-05T20:00:02Z PeachFullzZ 2 /* รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ */ wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ | name = สภานิติบัญญัติแห่งชาติ | coa_pic = | coa_res = | session_room = | session_res = | house_type = ระบบสภาเดียว | houses = | leader1_type = [[ประธานสภานิติบัญญัติแห่งชาติ|ประธาน]] | leader1 = [[เนติวิทย์ นวโชติ]] | party1 = | election1 = | leader2_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 1]] | leader2 = [[โฆษิต นวชาติ]] | party2 = | election2 = | leader3_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 2]] | leader3 = [[ณิชานันท์ ธนินทวรานนท์]] | party3 = | election3 = | members = 39 ที่นั่ง |structure1 = National Legislative Assembly of Thailand (2023).svg |structure1_res = 270px | house1 = | house2 = | political_groups1 = ได้รับการแต่งตั้งมาจากภาคส่วนต่าง ๆ<br />{{colorbox|#53639B}} [[บริษัท วานิเฉียนกรุป จำกัด]] (10)<br /> {{colorbox|#96E200}} [[พรรคสมัยใหม่]] (8)<br /> {{colorbox|#DBDBDB}} อิสระ (7)<br /> {{colorbox|#C8AC7E}} [[ข้าราชการ]] (6)<br /> {{colorbox|#CC2F29}} [[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] (5)<br />{{colorbox|#2ECC71}} [[แพทย์]] (2)<br /> {{colorbox|#008BD0}} [[พรรคประชาธิปัตย์]] (1)<br /> {{colorbox|#1A5CCC}} [[นักการเมืองอิสระ]] (1) | political_groups2 = | last_election1 = | next_election2 = | meeting_place = [[สัปปายะสภาสถาน]] [[เขตดุสิต]] [[กรุงเทพมหานคร]] [[ประเทศไทย]] | website = {{URL|https://discord.gg/ZeBQkrchEP}} }} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564]] == รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ == {{legend|#53639B|กลุ่มนักธุรกิจ (วานิเฉียนกรุป) (10)}} {{legend|#96E200|กลุ่มนักการเมือง (พรรคสมัยใหม่) (8)}} {{legend|#DBDBDB|กลุ่มอิสระ (7)}} {{legend|#C8AC7E|กลุ่มข้าราชการ (6)}} {{legend|#CC2F29|กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) (5)}} {{legend|#2ECC71|กลุ่มแพทย์ (2)}} {{legend|#008BD0|กลุ่มนักการเมือง (พรรคประชาธิปัตย์) (1)}} {{legend|#1A5CCC|กลุ่มนักการเมือง (อิสระ) (1)}} {| class="wikitable sortable" |- ! colspan=2 | กลุ่มการเมือง ! ชื่อ-นามสกุล ! อาชีพ ! หมายเหตุ |- | bgcolor = "#2ECC71"| | กลุ่มแพทย์ | ขะเหมียว ธาราวัชรจินดา | ผู้อำนวยการ[[โรงพยาบาลจุฬาลงกรณ์ สภากาชาดไทย]] | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | คิเอะ เสาร์แก้ว | คอนเทนต์ครีเอเตอร์ | |- | bgcolor = "#1A5CCC"| | กลุ่มนักการเมือง (อิสระ) | โฆษิต นวชาติ | อดีตประธานรัฐสภา และนักการเมือง | รองประธานสภาคนที่ 1 |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จรดล แซ่เหงียน | อธิบดี[[กรมศิลปากร]] | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จักรภพ เทเวศร์โยธิน | | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | จิน เดอฌอง ดูว์ วาณิช | ประธานเจ้าหน้าที่บริหารบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จิราติ ศักดา | เจ้าหน้าที่งานในพระประมุข | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | จุทาเทพยศะมหรนะ ธาราวัชรจินดา | รองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ซาลาห์ เออร์บาโน่ ดูว์ วาณิช | กรรมการอิสระบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ซีวาน ดูว์ วาณิช | รองประธานกรรมการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | ณิชานันท์ ธนินทวรานนท์ | เลขาธิการพรรคสมัยใหม่ | รองประธานสภาคนที่ 2 |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | แดนนีลีน เฉียน | ประธานเจ้าหน้าที่การเงินบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#2ECC71"| | กลุ่มแพทย์ | ธนวุฒิศ์นากิศา ภัทรเวชยสถิต | อดีตประธานประมุขมนตรี | ที่ปรึกษาประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | ธัณย์สิตา ธาราวัชรจินดา | พระมุขยวงศ์ และรองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | นลิน ศิริธนจริยานนท์ | กรรมการบริหารพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | นาถสุรีย์วิภา อรปรียา | สมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | นาธานาเอล ชาลส์ ดูว์ วาณิช | ประธานเจ้าหน้าที่เทคโนโลยีบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | เนติวิทย์ นวโชติ | อดีตพระประมุข และประธานศาลฎีกา | ประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | โนอา คอร์แยน ดูว์ วาณิช | ประธานเจ้าหน้าที่ปฏิบัติการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | บิลลีอัลมานี ธาราวัชรจินดา | รองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | เบญจา วรรณศิริลักษณ์ | กรรมการบริหารพรรคสมัยใหม่ | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | ภฑิล ชัยทรัพย์มั่นคง | | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | ภูติเดช ธาราวัชรจินดา | กรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | มงคลชาย แสงทวี | โฆษกพรรคสมัยใหม่ | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | รรรรรร ผิดหวัง | | เลขานุการประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | วสันต์ อุสมาน หมักคา | | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | วอลเตอร์ ธาราวัชรจินดา | ประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วารีทัศน์ ไวต์ | รองหัวหน้าพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วิทยาภรณ์ อารียไพศาล | รองหัวหน้าพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วีรยุทธ วัลพัฒวาณิช | สมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | ศักดิ์สยาม ศิลปไชย | เจ้าพนักงานธุรการปฏิบัติงาน [[กระทรวงการต่างประเทศ]] | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ศิริเนตรดารณี ปรียาพัชรวิลาศ วินิจเมธา | กรรมการที่ไม่เป็นผู้บริหารบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | ศุภวิชญ์ พึ่งพารักษ์ | | โฆษกประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | สกธินชารินทร์พธา นวชาติ | | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | สรายุทธ โครตอตร | หัวหน้าพรรคสมัยใหม่ และอดีตอนุญาโตตุลาการ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | สิฟริตต์ เฉียน | | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | [[อนาวิน สุขเกษมอดิศักดิ์]] | อดีตตุลาการศาลรัฐธรรมนูญ อดีตหัวหน้าและสมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | อเดลเบิร์ต เฉียน | ประธานกรรมการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#008BD0"| | กลุ่มนักการเมือง (พรรคประชาธิปัตย์) | อานุภาพ คุณูปจางบริรักษ์ | นายกรัฐมนตรี และหัวหน้าพรรคประชาธิปัตย์ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | เอสดราส โนบิลิส ดูว์ วาณิช | ประธานเจ้าหน้าที่สารสนเทศบริษัท วานิเฉียนกรุป จำกัด | |- |} 7c75f25833a74610742e4adac583393b331259d6 175 174 2023-10-06T04:16:20Z PeachFullzZ 2 /* รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ */ wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ | name = สภานิติบัญญัติแห่งชาติ | coa_pic = | coa_res = | session_room = | session_res = | house_type = ระบบสภาเดียว | houses = | leader1_type = [[ประธานสภานิติบัญญัติแห่งชาติ|ประธาน]] | leader1 = [[เนติวิทย์ นวโชติ]] | party1 = | election1 = | leader2_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 1]] | leader2 = [[โฆษิต นวชาติ]] | party2 = | election2 = | leader3_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 2]] | leader3 = [[ณิชานันท์ ธนินทวรานนท์]] | party3 = | election3 = | members = 39 ที่นั่ง |structure1 = National Legislative Assembly of Thailand (2023).svg |structure1_res = 270px | house1 = | house2 = | political_groups1 = ได้รับการแต่งตั้งมาจากภาคส่วนต่าง ๆ<br />{{colorbox|#53639B}} [[บริษัท วานิเฉียนกรุป จำกัด]] (10)<br /> {{colorbox|#96E200}} [[พรรคสมัยใหม่]] (8)<br /> {{colorbox|#DBDBDB}} อิสระ (7)<br /> {{colorbox|#C8AC7E}} [[ข้าราชการ]] (6)<br /> {{colorbox|#CC2F29}} [[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] (5)<br />{{colorbox|#2ECC71}} [[แพทย์]] (2)<br /> {{colorbox|#008BD0}} [[พรรคประชาธิปัตย์]] (1)<br /> {{colorbox|#1A5CCC}} [[นักการเมืองอิสระ]] (1) | political_groups2 = | last_election1 = | next_election2 = | meeting_place = [[สัปปายะสภาสถาน]] [[เขตดุสิต]] [[กรุงเทพมหานคร]] [[ประเทศไทย]] | website = {{URL|https://discord.gg/ZeBQkrchEP}} }} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564]] == รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ == {{legend|#53639B|กลุ่มนักธุรกิจ (วานิเฉียนกรุป) (10)}} {{legend|#96E200|กลุ่มนักการเมือง (พรรคสมัยใหม่) (8)}} {{legend|#DBDBDB|กลุ่มอิสระ (7)}} {{legend|#C8AC7E|กลุ่มข้าราชการ (6)}} {{legend|#CC2F29|กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) (5)}} {{legend|#2ECC71|กลุ่มแพทย์ (2)}} {{legend|#008BD0|กลุ่มนักการเมือง (พรรคประชาธิปัตย์) (1)}} {{legend|#1A5CCC|กลุ่มนักการเมือง (อิสระ) (1)}} {| class="wikitable sortable" |- ! colspan=2 | กลุ่มการเมือง ! ชื่อ-นามสกุล ! อาชีพ ! หมายเหตุ |- | bgcolor = "#2ECC71"| | กลุ่มแพทย์ | ขะเหมียว ธาราวัชรจินดา | ผู้อำนวยการ[[โรงพยาบาลจุฬาลงกรณ์ สภากาชาดไทย]] | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | คิเอะ เสาร์แก้ว | คอนเทนต์ครีเอเตอร์ | |- | bgcolor = "#1A5CCC"| | กลุ่มนักการเมือง (อิสระ) | โฆษิต นวชาติ | อดีตประธานรัฐสภา และนักการเมือง | รองประธานสภาคนที่ 1 |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จรดล แซ่เหงียน | อธิบดี[[กรมศิลปากร]] | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จักรภพ เทเวศร์โยธิน | | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | จิน เดอฌอง ดูว์ วาณิช | ประธานเจ้าหน้าที่บริหารบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จิราติ ศักดา | เจ้าหน้าที่งานในพระประมุข | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | จุทาเทพยศะมหรนะ ธาราวัชรจินดา | รองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ซาลาห์ เออร์บาโน่ ดูว์ วาณิช | กรรมการอิสระบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ซีวาน ดูว์ วาณิช | รองประธานกรรมการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | ณิชานันท์ ธนินทวรานนท์ | เลขาธิการพรรคสมัยใหม่ | รองประธานสภาคนที่ 2 |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | แดนนีลีน เฉียน | ประธานเจ้าหน้าที่การเงินบริษัท วานิเฉียนกรุป จำกัด | ลาออก 31 สิงหาคม 2566 (ยื่นหนังสือ 31 สิงหาคม 2566) |- | bgcolor = "#2ECC71"| | กลุ่มแพทย์ | ธนวุฒิศ์นากิศา ภัทรเวชยสถิต | อดีตประธานประมุขมนตรี | ที่ปรึกษาประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | ธัณย์สิตา ธาราวัชรจินดา | พระมุขยวงศ์ และรองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | นลิน ศิริธนจริยานนท์ | กรรมการบริหารพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | นาถสุรีย์วิภา อรปรียา | สมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | นาธานาเอล ชาลส์ ดูว์ วาณิช | ประธานเจ้าหน้าที่เทคโนโลยีบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | เนติวิทย์ นวโชติ | อดีตพระประมุข และประธานศาลฎีกา | ประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | โนอา คอร์แยน ดูว์ วาณิช | ประธานเจ้าหน้าที่ปฏิบัติการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | บิลลีอัลมานี ธาราวัชรจินดา | รองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | เบญจา วรรณศิริลักษณ์ | กรรมการบริหารพรรคสมัยใหม่ | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | ภฑิล ชัยทรัพย์มั่นคง | | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | ภูติเดช ธาราวัชรจินดา | กรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | มงคลชาย แสงทวี | โฆษกพรรคสมัยใหม่ | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | รรรรรร ผิดหวัง | | เลขานุการประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | วสันต์ อุสมาน หมักคา | | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | วอลเตอร์ ธาราวัชรจินดา | ประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วารีทัศน์ ไวต์ | รองหัวหน้าพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วิทยาภรณ์ อารียไพศาล | รองหัวหน้าพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วีรยุทธ วัลพัฒวาณิช | สมาชิกพรรคสมัยใหม่ | ลาออก 5 สิงหาคม 2566 (ยื่นหนังสือ 5 สิงหาคม 2566) |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | ศักดิ์สยาม ศิลปไชย | เจ้าพนักงานธุรการปฏิบัติงาน [[กระทรวงการต่างประเทศ]] | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ศิริเนตรดารณี ปรียาพัชรวิลาศ วินิจเมธา | กรรมการที่ไม่เป็นผู้บริหารบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | ศุภวิชญ์ พึ่งพารักษ์ | | โฆษกประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | สกธินชารินทร์พธา นวชาติ | | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | สรายุทธ โครตอตร | หัวหน้าพรรคสมัยใหม่ และอดีตอนุญาโตตุลาการ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | สิฟริตต์ เฉียน | | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | [[อนาวิน สุขเกษมอดิศักดิ์]] | อดีตตุลาการศาลรัฐธรรมนูญ อดีตหัวหน้าและสมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | อเดลเบิร์ต เฉียน | ประธานกรรมการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#008BD0"| | กลุ่มนักการเมือง (พรรคประชาธิปัตย์) | อานุภาพ คุณูปจางบริรักษ์ | นายกรัฐมนตรี และหัวหน้าพรรคประชาธิปัตย์ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | เอสดราส โนบิลิส ดูว์ วาณิช | ประธานเจ้าหน้าที่สารสนเทศบริษัท วานิเฉียนกรุป จำกัด | |- |} 231055f9ec91047abfc4d2250d660570b7707eb5 180 175 2023-10-06T04:53:29Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ | name = สภานิติบัญญัติแห่งชาติ | coa_pic = | coa_res = | session_room = | session_res = | house_type = ระบบสภาเดียว | houses = | leader1_type = [[ประธานสภานิติบัญญัติแห่งชาติ|ประธาน]] | leader1 = [[เนติวิทย์ นวโชติ]] | party1 = | election1 = | leader2_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 1]] | leader2 = [[โฆษิต นวชาติ]] | party2 = | election2 = | leader3_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 2]] | leader3 = [[ณิชานันท์ ธนินทวรานนท์]] | party3 = | election3 = | members = 39 ที่นั่ง |structure1 = National Legislative Assembly of Thailand (2023).svg |structure1_res = 270px | house1 = | house2 = | political_groups1 = ได้รับการแต่งตั้งมาจากภาคส่วนต่าง ๆ<br />{{colorbox|#53639B}} [[บริษัท วานิเฉียนกรุป จำกัด]] (10)<br /> {{colorbox|#96E200}} [[พรรคสมัยใหม่]] (8)<br /> {{colorbox|#DBDBDB}} อิสระ (7)<br /> {{colorbox|#C8AC7E}} [[ข้าราชการ]] (6)<br /> {{colorbox|#CC2F29}} [[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] (5)<br />{{colorbox|#2ECC71}} [[แพทย์]] (2)<br /> {{colorbox|#008BD0}} [[พรรคประชาธิปัตย์]] (1)<br /> {{colorbox|#1A5CCC}} [[นักการเมืองอิสระ]] (1) | political_groups2 = | last_election1 = | next_election2 = | meeting_place = [[สัปปายะสภาสถาน]] [[เขตดุสิต]] [[กรุงเทพมหานคร]] [[ประเทศไทย]] | website = {{URL|https://discord.gg/ZeBQkrchEP}} }} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564]] == รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ == {{legend|#53639B|กลุ่มนักธุรกิจ (วานิเฉียนกรุป) (10)}} {{legend|#96E200|กลุ่มนักการเมือง (พรรคสมัยใหม่) (8)}} {{legend|#DBDBDB|กลุ่มอิสระ (7)}} {{legend|#C8AC7E|กลุ่มข้าราชการ (6)}} {{legend|#CC2F29|กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) (5)}} {{legend|#2ECC71|กลุ่มแพทย์ (2)}} {{legend|#008BD0|กลุ่มนักการเมือง (พรรคประชาธิปัตย์) (1)}} {{legend|#1A5CCC|กลุ่มนักการเมือง (อิสระ) (1)}} {| class="wikitable sortable" |- ! colspan=2 | กลุ่มการเมือง ! ชื่อ-นามสกุล ! อาชีพ ! หมายเหตุ |- | bgcolor = "#2ECC71"| | กลุ่มแพทย์ | ขะเหมียว ธาราวัชรจินดา | ผู้อำนวยการ[[โรงพยาบาลจุฬาลงกรณ์ สภากาชาดไทย]] | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | คิเอะ เสาร์แก้ว | คอนเทนต์ครีเอเตอร์ | |- | bgcolor = "#1A5CCC"| | กลุ่มนักการเมือง (อิสระ) | โฆษิต นวชาติ | อดีตประธานรัฐสภา และนักการเมือง | รองประธานสภาคนที่ 1 |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จรดล แซ่เหงียน | อธิบดี[[กรมศิลปากร]] | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จักรภพ เทเวศร์โยธิน | | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | จิน เดอฌอง ดูว์ วาณิช | ประธานเจ้าหน้าที่บริหารบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จิราติ ศักดา | เจ้าหน้าที่งานในพระประมุข | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | จุทาเทพยศะมหรนะ ธาราวัชรจินดา | รองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ซาลาห์ เออร์บาโน่ ดูว์ วาณิช | กรรมการอิสระบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ซีวาน ดูว์ วาณิช | รองประธานกรรมการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | ณิชานันท์ ธนินทวรานนท์ | เลขาธิการพรรคสมัยใหม่ | รองประธานสภาคนที่ 2 |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | แดนนีลีน เฉียน | ประธานเจ้าหน้าที่การเงินบริษัท วานิเฉียนกรุป จำกัด | ลาออก 31 สิงหาคม 2566 (ยื่นหนังสือ 31 สิงหาคม 2566) |- | bgcolor = "#2ECC71"| | กลุ่มแพทย์ | ธนวุฒิศ์นากิศา ภัทรเวชยสถิต | อดีตประธานประมุขมนตรี | ที่ปรึกษาประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | ธัณย์สิตา ธาราวัชรจินดา | พระมุขยวงศ์ และรองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | นลิน ศิริธนจริยานนท์ | กรรมการบริหารพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | นาถสุรีย์วิภา อรปรียา | สมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | นาธานาเอล ชาลส์ ดูว์ วาณิช | ประธานเจ้าหน้าที่เทคโนโลยีบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | เนติวิทย์ นวโชติ | อดีตพระประมุข และประธานศาลฎีกา | ประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | โนอา คอร์แยน ดูว์ วาณิช | ประธานเจ้าหน้าที่ปฏิบัติการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | บิลลีอัลมานี ธาราวัชรจินดา | รองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | เบญจา วรรณศิริลักษณ์ | กรรมการบริหารพรรคสมัยใหม่ | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | ภฑิล ชัยทรัพย์มั่นคง | | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | ภูติเดช ธาราวัชรจินดา | กรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | มงคลชาย แสงทวี | โฆษกพรรคสมัยใหม่ | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | รรรรรร ผิดหวัง | | เลขานุการประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | วสันต์ อุสมาน หมักคา | | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | วอลเตอร์ ธาราวัชรจินดา | ประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วารีทัศน์ ไวต์ | รองหัวหน้าพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วิทยาภรณ์ อารียไพศาล | รองหัวหน้าพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วีรยุทธ วัลพัฒวาณิช | สมาชิกพรรคสมัยใหม่ | ลาออก 5 สิงหาคม 2566 (ยื่นหนังสือ 5 สิงหาคม 2566) |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | ศักดิ์สยาม ศิลปไชย | เจ้าพนักงานธุรการปฏิบัติงาน [[กระทรวงการต่างประเทศ]] | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ศิริเนตรดารณี ปรียาพัชรวิลาศ วินิจเมธา | กรรมการที่ไม่เป็นผู้บริหารบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | ศุภวิชญ์ พึ่งพารักษ์ | | โฆษกประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | สกธินชารินทร์พธา นวชาติ | | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | สรายุทธ โครตอตร | หัวหน้าพรรคสมัยใหม่ และอดีตอนุญาโตตุลาการ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | สิฟริตต์ เฉียน | | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | [[อนาวิน สุขเกษมอดิศักดิ์]] | อดีตตุลาการศาลรัฐธรรมนูญ อดีตหัวหน้าและสมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | อเดลเบิร์ต เฉียน | ประธานกรรมการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#008BD0"| | กลุ่มนักการเมือง (พรรคประชาธิปัตย์) | [[อานุภาพ คุณูปจางบริรักษ์]] | นายกรัฐมนตรี และหัวหน้าพรรคประชาธิปัตย์ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | เอสดราส โนบิลิส ดูว์ วาณิช | ประธานเจ้าหน้าที่สารสนเทศบริษัท วานิเฉียนกรุป จำกัด | |- |} 475578befa417dd8a18fa065f708335832f1c0dd 182 180 2023-10-06T10:51:01Z PeachFullzZ 2 /* รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ */ wikitext text/x-wiki {{กล่องข้อมูล สภานิติบัญญัติ | name = สภานิติบัญญัติแห่งชาติ | coa_pic = | coa_res = | session_room = | session_res = | house_type = ระบบสภาเดียว | houses = | leader1_type = [[ประธานสภานิติบัญญัติแห่งชาติ|ประธาน]] | leader1 = [[เนติวิทย์ นวโชติ]] | party1 = | election1 = | leader2_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 1]] | leader2 = [[โฆษิต นวชาติ]] | party2 = | election2 = | leader3_type = [[รองประธานสภานิติบัญญัติแห่งชาติ|รองประธานคนที่ 2]] | leader3 = [[ณิชานันท์ ธนินทวรานนท์]] | party3 = | election3 = | members = 39 ที่นั่ง |structure1 = National Legislative Assembly of Thailand (2023).svg |structure1_res = 270px | house1 = | house2 = | political_groups1 = ได้รับการแต่งตั้งมาจากภาคส่วนต่าง ๆ<br />{{colorbox|#53639B}} [[บริษัท วานิเฉียนกรุป จำกัด]] (10)<br /> {{colorbox|#96E200}} [[พรรคสมัยใหม่]] (8)<br /> {{colorbox|#DBDBDB}} อิสระ (7)<br /> {{colorbox|#C8AC7E}} [[ข้าราชการ]] (6)<br /> {{colorbox|#CC2F29}} [[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] (5)<br />{{colorbox|#2ECC71}} [[แพทย์]] (2)<br /> {{colorbox|#008BD0}} [[พรรคประชาธิปัตย์]] (1)<br /> {{colorbox|#1A5CCC}} [[นักการเมืองอิสระ]] (1) | political_groups2 = | last_election1 = | next_election2 = | meeting_place = [[สัปปายะสภาสถาน]] [[เขตดุสิต]] [[กรุงเทพมหานคร]] [[ประเทศไทย]] | website = {{URL|https://discord.gg/ZeBQkrchEP}} }} '''สภานิติบัญญัติแห่งชาติ พ.ศ. 2566''' เป็นสภานิติบัญญัติระบบสภาเดี่ยวของ[[ประเทศไทย]] ซึ่งจัดตั้งขึ้นตาม[[รัฐธรรมนูญแห่งราชอาณาจักรไทย พุทธศักราช 2564]] == รายชื่อสมาชิกสภานิติบัญญัติแห่งชาติ == {{legend|#53639B|กลุ่มนักธุรกิจ (วานิเฉียนกรุป) (10)}} {{legend|#96E200|กลุ่มนักการเมือง (พรรคสมัยใหม่) (8)}} {{legend|#DBDBDB|กลุ่มอิสระ (7)}} {{legend|#C8AC7E|กลุ่มข้าราชการ (6)}} {{legend|#CC2F29|กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) (5)}} {{legend|#2ECC71|กลุ่มแพทย์ (2)}} {{legend|#008BD0|กลุ่มนักการเมือง (พรรคประชาธิปัตย์) (1)}} {{legend|#1A5CCC|กลุ่มนักการเมือง (อิสระ) (1)}} {| class="wikitable sortable" |- ! colspan=2 | กลุ่มการเมือง ! ชื่อ-นามสกุล ! อาชีพ ! หมายเหตุ |- | bgcolor = "#2ECC71"| | กลุ่มแพทย์ | ขะเหมียว ธาราวัชรจินดา | ผู้อำนวยการ[[โรงพยาบาลจุฬาลงกรณ์ สภากาชาดไทย]] | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | คิเอะ เสาร์แก้ว | คอนเทนต์ครีเอเตอร์ | |- | bgcolor = "#1A5CCC"| | กลุ่มนักการเมือง (อิสระ) | โฆษิต นวชาติ | อดีตประธานรัฐสภา และนักการเมือง | รองประธานสภาคนที่ 1 |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จรดล แซ่เหงียน | อธิบดี[[กรมศิลปากร]] | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จักรภพ เทเวศร์โยธิน | | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | จิน เดอฌอง ดูว์ วาณิช | ประธานเจ้าหน้าที่บริหารบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | จิราติ ศักดา | เจ้าหน้าที่งานในพระประมุข | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | จุทาเทพยศะมหรนะ ธาราวัชรจินดา | รองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ซาลาห์ เออร์บาโน่ ดูว์ วาณิช | กรรมการอิสระบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ซีวาน ดูว์ วาณิช | รองประธานกรรมการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | ณิชานันท์ ธนินทวรานนท์ | เลขาธิการพรรคสมัยใหม่ | รองประธานสภาคนที่ 2 |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | แดนนีลีน เฉียน | ประธานเจ้าหน้าที่การเงินบริษัท วานิเฉียนกรุป จำกัด | ลาออก 31 สิงหาคม 2566 (ยื่นหนังสือ 31 สิงหาคม 2566) |- | bgcolor = "#2ECC71"| | กลุ่มแพทย์ | ธนวุฒิศ์นากิศา ภัทรเวชยสถิต | อดีตประธานประมุขมนตรี | ที่ปรึกษาประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | ธัณย์สิตา ธาราวัชรจินดา | พระมุขยวงศ์ และรองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | นลิน ศิริธนจริยานนท์ | กรรมการบริหารพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | นาถสุรีย์วิภา อรปรียา | สมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | นาธานาเอล ชาลส์ ดูว์ วาณิช | ประธานเจ้าหน้าที่เทคโนโลยีบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | เนติวิทย์ นวโชติ | อดีตพระประมุข และประธานศาลฎีกา | ประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | โนอา คอร์แยน ดูว์ วาณิช | ประธานเจ้าหน้าที่ปฏิบัติการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | บิลลีอัลมานี ธาราวัชรจินดา | รองประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | เบญจา วรรณศิริลักษณ์ | กรรมการบริหารพรรคสมัยใหม่ | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | ภฑิล ชัยทรัพย์มั่นคง | | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | ภูติเดช ธาราวัชรจินดา | กรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | มงคลชาย แสงทวี | โฆษกพรรคสมัยใหม่ | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | รรรรรร ผิดหวัง | | เลขานุการประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | วสันต์ อุสมาน หมักคา | | |- | bgcolor = "#CC2F29"| | กลุ่มนักธุรกิจ (เครือตั้งหวังเจ๊ง) | วอลเตอร์ ธาราวัชรจินดา | ประธานกรรมการบริษัท เครือตั้งหวังเจ๊ง จำกัด | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วารีทัศน์ ไวต์ | รองหัวหน้าพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วิทยาภรณ์ อารียไพศาล | รองหัวหน้าพรรคสมัยใหม่ | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | วีรยุทธ วัลพัฒวาณิช | สมาชิกพรรคสมัยใหม่ | ลาออก 5 สิงหาคม 2566 (ยื่นหนังสือ 5 สิงหาคม 2566) |- | bgcolor = "#C8AC7E"| | กลุ่มข้าราชการ | ศักดิ์สยาม ศิลปไชย | เจ้าพนักงานธุรการปฏิบัติงาน [[กระทรวงการต่างประเทศ]] | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | ศิริเนตรดารณี ปรียาพัชรวิลาศ วินิจเมธา | กรรมการที่ไม่เป็นผู้บริหารบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | ศุภวิชญ์ พึ่งพารักษ์ | | โฆษกประธานสภานิติบัญญัติแห่งชาติ |- | bgcolor = "#DBDBDB"| | กลุ่มอิสระ | สกธินชารินทร์พธา นวชาติ | | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | [[สรายุทธ โครตอตร]] | หัวหน้าพรรคสมัยใหม่ และอดีตอนุญาโตตุลาการ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | สิฟริตต์ เฉียน | | |- | bgcolor = "#96E200"| | กลุ่มนักการเมือง (พรรคสมัยใหม่) | [[อนาวิน สุขเกษมอดิศักดิ์]] | อดีตตุลาการศาลรัฐธรรมนูญ อดีตหัวหน้าและสมาชิกพรรคสมัยใหม่ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | อเดลเบิร์ต เฉียน | ประธานกรรมการบริษัท วานิเฉียนกรุป จำกัด | |- | bgcolor = "#008BD0"| | กลุ่มนักการเมือง (พรรคประชาธิปัตย์) | [[อานุภาพ คุณูปจางบริรักษ์]] | นายกรัฐมนตรี และหัวหน้าพรรคประชาธิปัตย์ | |- | bgcolor = "#53639B"| | กลุ่มนักธุรกิจ (วานิเฉียนกรุป) | เอสดราส โนบิลิส ดูว์ วาณิช | ประธานเจ้าหน้าที่สารสนเทศบริษัท วานิเฉียนกรุป จำกัด | |- |} 5ef3409c03d28bdf153cfca1ed0fa7abf639c175 มอดูล:Uses TemplateStyles/config 828 84 163 2023-10-05T17:06:33Z PeachFullzZ 2 สร้างหน้าด้วย "local cfg = {} -- Don’t touch this line. -- Subpage blacklist: these subpages will not be categorized (except for the -- error category, which is always added if there is an error). -- For example “Template:Foo/doc” matches the `doc = true` rule, so it will have -- no categories. “Template:Foo” and “Template:Foo/documentation” match no rules, -- so they *will* have categories. All rules should be in the -- ['<subpage name>'] = true,..." Scribunto text/plain local cfg = {} -- Don’t touch this line. -- Subpage blacklist: these subpages will not be categorized (except for the -- error category, which is always added if there is an error). -- For example “Template:Foo/doc” matches the `doc = true` rule, so it will have -- no categories. “Template:Foo” and “Template:Foo/documentation” match no rules, -- so they *will* have categories. All rules should be in the -- ['<subpage name>'] = true, -- format. cfg['subpage_blacklist'] = { ['doc'] = true, ['sandbox'] = true, ['sandbox2'] = true, ['testcases'] = true, } -- Sandbox title: if the stylesheet’s title is <template>/<stylesheet>.css, the -- stylesheet’s sandbox is expected to be at <template>/<sandbox_title>/<stylesheet>.css -- Set to nil to disable sandbox links. cfg['sandbox_title'] = 'sandbox' -- Error category: this category is added if the module call contains errors -- (e.g. no stylesheet listed). A category name without namespace, or nil -- to disable categorization (not recommended). cfg['error_category'] = 'Uses TemplateStyles templates with errors' -- Default category: this category is added if no custom category is specified -- in module/template call. A category name without namespace, or nil -- to disable categorization. cfg['default_category'] = 'Templates using TemplateStyles' -- Protection conflict category: this category is added if the protection level -- of any stylesheet is lower than the protection level of the template. A category name -- without namespace, or nil to disable categorization (not recommended). cfg['protection_conflict_category'] = 'Templates using TemplateStyles with a different protection level' -- Hierarchy of protection levels, used to determine whether one protection level is lower -- than another and thus should populate protection_conflict_category. No protection is treated as zero cfg['protection_hierarchy'] = { autoconfirmed = 1, extendedconfirmed = 2, templateeditor = 3, sysop = 4 } -- Padlock pattern: Lua pattern to search on protected stylesheets for, or nil -- to disable padlock check. cfg['padlock_pattern'] = '{{pp-' -- Missing padlock category: this category is added if a protected stylesheet -- doesn’t contain any padlock template (specified by the above Lua pattern). -- A category name without namespace (no nil allowed) if the pattern is not nil, -- unused (and thus may be nil) otherwise. cfg['missing_padlock_category'] = 'Templates using TemplateStyles without padlocks' return cfg -- Don’t touch this line. 58e7a37c44f6ea3f6b8af54a559d696cc7256493 164 163 2023-10-05T17:06:55Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Uses TemplateStyles/config]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local cfg = {} -- Don’t touch this line. -- Subpage blacklist: these subpages will not be categorized (except for the -- error category, which is always added if there is an error). -- For example “Template:Foo/doc” matches the `doc = true` rule, so it will have -- no categories. “Template:Foo” and “Template:Foo/documentation” match no rules, -- so they *will* have categories. All rules should be in the -- ['<subpage name>'] = true, -- format. cfg['subpage_blacklist'] = { ['doc'] = true, ['sandbox'] = true, ['sandbox2'] = true, ['testcases'] = true, } -- Sandbox title: if the stylesheet’s title is <template>/<stylesheet>.css, the -- stylesheet’s sandbox is expected to be at <template>/<sandbox_title>/<stylesheet>.css -- Set to nil to disable sandbox links. cfg['sandbox_title'] = 'sandbox' -- Error category: this category is added if the module call contains errors -- (e.g. no stylesheet listed). A category name without namespace, or nil -- to disable categorization (not recommended). cfg['error_category'] = 'Uses TemplateStyles templates with errors' -- Default category: this category is added if no custom category is specified -- in module/template call. A category name without namespace, or nil -- to disable categorization. cfg['default_category'] = 'Templates using TemplateStyles' -- Protection conflict category: this category is added if the protection level -- of any stylesheet is lower than the protection level of the template. A category name -- without namespace, or nil to disable categorization (not recommended). cfg['protection_conflict_category'] = 'Templates using TemplateStyles with a different protection level' -- Hierarchy of protection levels, used to determine whether one protection level is lower -- than another and thus should populate protection_conflict_category. No protection is treated as zero cfg['protection_hierarchy'] = { autoconfirmed = 1, extendedconfirmed = 2, templateeditor = 3, sysop = 4 } -- Padlock pattern: Lua pattern to search on protected stylesheets for, or nil -- to disable padlock check. cfg['padlock_pattern'] = '{{pp-' -- Missing padlock category: this category is added if a protected stylesheet -- doesn’t contain any padlock template (specified by the above Lua pattern). -- A category name without namespace (no nil allowed) if the pattern is not nil, -- unused (and thus may be nil) otherwise. cfg['missing_padlock_category'] = 'Templates using TemplateStyles without padlocks' return cfg -- Don’t touch this line. 58e7a37c44f6ea3f6b8af54a559d696cc7256493 แม่แบบ:Greater color contrast ratio 10 85 165 2023-10-05T17:11:07Z PeachFullzZ 2 สร้างหน้าด้วย "<includeonly>{{safesubst:#invoke:Color contrast|greatercontrast}}</includeonly><noinclude> {{documentation}} </noinclude>" wikitext text/x-wiki <includeonly>{{safesubst:#invoke:Color contrast|greatercontrast}}</includeonly><noinclude> {{documentation}} </noinclude> 08f37e0034cd82c11211404926ee850c49779567 166 165 2023-10-05T17:11:20Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Greater color contrast ratio]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki <includeonly>{{safesubst:#invoke:Color contrast|greatercontrast}}</includeonly><noinclude> {{documentation}} </noinclude> 08f37e0034cd82c11211404926ee850c49779567 มอดูล:Color contrast 828 86 167 2023-10-05T17:12:44Z PeachFullzZ 2 สร้างหน้าด้วย "-- -- This module implements -- {{Color contrast ratio}} -- {{Greater color contrast ratio}} -- {{ColorToLum}} -- {{RGBColorToLum}} -- local p = {} local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' ) local function sRGB (v) if (v <= 0.03928) then v = v / 12.92 else v = math.pow((v+0.055)/1.055, 2.4) end return v end local function rgbdec2lum(R, G, B) if ( 0 <= R and R < 256 and 0 <= G and G < 256 and 0 <= B and B < 256 ) t..." Scribunto text/plain -- -- This module implements -- {{Color contrast ratio}} -- {{Greater color contrast ratio}} -- {{ColorToLum}} -- {{RGBColorToLum}} -- local p = {} local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' ) local function sRGB (v) if (v <= 0.03928) then v = v / 12.92 else v = math.pow((v+0.055)/1.055, 2.4) end return v end local function rgbdec2lum(R, G, B) if ( 0 <= R and R < 256 and 0 <= G and G < 256 and 0 <= B and B < 256 ) then return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255) else return '' end end local function hsl2lum(h, s, l) if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then local c = (1 - math.abs(2*l - 1))*s local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) ) local m = l - c/2 local r, g, b = m, m, m if( 0 <= h and h < 60 ) then r = r + c g = g + x elseif( 60 <= h and h < 120 ) then r = r + x g = g + c elseif( 120 <= h and h < 180 ) then g = g + c b = b + x elseif( 180 <= h and h < 240 ) then g = g + x b = b + c elseif( 240 <= h and h < 300 ) then r = r + x b = b + c elseif( 300 <= h and h < 360 ) then r = r + c b = b + x end return rgbdec2lum(255*r, 255*g, 255*b) else return '' end end local function color2lum(c) if (c == nil) then return '' end -- html '#' entity c = c:gsub("&#35;", "#") -- whitespace c = c:match( '^%s*(.-)[%s;]*$' ) -- unstrip nowiki strip markers c = mw.text.unstripNoWiki(c) -- lowercase c = c:lower() -- first try to look it up local L = HTMLcolor[c] if (L ~= nil) then return L end -- convert from hsl if mw.ustring.match(c,'^hsl%([%s]*[0-9][0-9%.]*[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then local h, s, l = mw.ustring.match(c,'^hsl%([%s]*([0-9][0-9%.]*)[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$') return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100) end -- convert from rgb if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*%)$') then local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*%)$') return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B)) end -- convert from rgb percent if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$') return rgbdec2lum(255*tonumber(R)/100, 255*tonumber(G)/100, 255*tonumber(B)/100) end -- remove leading # (if there is one) and whitespace c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$') -- split into rgb local cs = mw.text.split(c or '', '') if( #cs == 6 ) then local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2]) local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4]) local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6]) return rgbdec2lum(R, G, B) elseif ( #cs == 3 ) then local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1]) local G = 16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2]) local B = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3]) return rgbdec2lum(R, G, B) end -- failure, return blank return '' end -- This exports the function for use in other modules. -- The colour is passed as a string. function p._lum(color) return color2lum(color) end function p._greatercontrast(args) local bias = tonumber(args['bias'] or '0') or 0 local css = (args['css'] and args['css'] ~= '') and true or false local v1 = color2lum(args[1] or '') local c2 = args[2] or '#FFFFFF' local v2 = color2lum(c2) local c3 = args[3] or '#000000' local v3 = color2lum(c3) local ratio1 = -1; local ratio2 = -1; if (type(v1) == 'number' and type(v2) == 'number') then ratio1 = (v2 + 0.05)/(v1 + 0.05) ratio1 = (ratio1 < 1) and 1/ratio1 or ratio1 end if (type(v1) == 'number' and type(v3) == 'number') then ratio2 = (v3 + 0.05)/(v1 + 0.05) ratio2 = (ratio2 < 1) and 1/ratio2 or ratio2 end if css then local c1 = args[1] or '' if mw.ustring.match(c1, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') or mw.ustring.match(c1, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') then c1 = '#' .. c1 end if mw.ustring.match(c2, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') or mw.ustring.match(c2, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') then c2 = '#' .. c2 end if mw.ustring.match(v3, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') or mw.ustring.match(v3, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') then c3 = '#' .. c3 end return 'background-color:' .. c1 .. '; color:' .. ((ratio1 > 0) and (ratio2 > 0) and ((ratio1 + bias > ratio2) and c2 or c3) or '') .. ';' end return (ratio1 > 0) and (ratio2 > 0) and ((ratio1 + bias > ratio2) and c2 or c3) or '' end function p._ratio(args) local v1 = color2lum(args[1]) local v2 = color2lum(args[2]) if (type(v1) == 'number' and type(v2) == 'number') then -- v1 should be the brighter of the two. if v2 > v1 then v1, v2 = v2, v1 end return (v1 + 0.05)/(v2 + 0.05) else return args['error'] or '?' end end function p._styleratio(args) local style = (args[1] or ''):lower() local bg, fg = 'white', 'black' local lum_bg, lum_fg = 1, 0 if args[2] then local lum = color2lum(args[2]) if lum ~= '' then bg, lum_bg = args[2], lum end end if args[3] then local lum = color2lum(args[3]) if lum ~= '' then fg, lum_fg = args[3], lum end end local slist = mw.text.split(mw.ustring.gsub(mw.ustring.gsub(style or '', '&#[Xx]23;', '#'), '&#35;', '#'), ';') for k = 1,#slist do local s = slist[k] local k,v = s:match( '^[%s]*([^:]-):([^:]-)[%s;]*$' ) k = k or '' v = v or '' if (k:match('^[%s]*(background)[%s]*$') or k:match('^[%s]*(background%-color)[%s]*$')) then local lum = color2lum(v) if( lum ~= '' ) then bg, lum_bg = v, lum end elseif (k:match('^[%s]*(color)[%s]*$')) then local lum = color2lum(v) if( lum ~= '' ) then bg, lum_fg = v, lum end end end if lum_bg > lum_fg then return (lum_bg + 0.05)/(lum_fg + 0.05) else return (lum_fg + 0.05)/(lum_bg + 0.05) end end --[[ Use {{#invoke:Color contrast|somecolor}} directly or {{#invoke:Color contrast}} from a wrapper template. Parameters: -- |1= — required; A color to check. --]] function p.lum(frame) local color = frame.args[1] or frame:getParent().args[1] return p._lum(color) end function p.ratio(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._ratio(args) end function p.styleratio(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._styleratio(args) end function p.greatercontrast(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._greatercontrast(args) end return p 1e399769117591366a63f62996c9a407077cc711 168 167 2023-10-05T17:13:03Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Color contrast]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- -- This module implements -- {{Color contrast ratio}} -- {{Greater color contrast ratio}} -- {{ColorToLum}} -- {{RGBColorToLum}} -- local p = {} local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' ) local function sRGB (v) if (v <= 0.03928) then v = v / 12.92 else v = math.pow((v+0.055)/1.055, 2.4) end return v end local function rgbdec2lum(R, G, B) if ( 0 <= R and R < 256 and 0 <= G and G < 256 and 0 <= B and B < 256 ) then return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255) else return '' end end local function hsl2lum(h, s, l) if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then local c = (1 - math.abs(2*l - 1))*s local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) ) local m = l - c/2 local r, g, b = m, m, m if( 0 <= h and h < 60 ) then r = r + c g = g + x elseif( 60 <= h and h < 120 ) then r = r + x g = g + c elseif( 120 <= h and h < 180 ) then g = g + c b = b + x elseif( 180 <= h and h < 240 ) then g = g + x b = b + c elseif( 240 <= h and h < 300 ) then r = r + x b = b + c elseif( 300 <= h and h < 360 ) then r = r + c b = b + x end return rgbdec2lum(255*r, 255*g, 255*b) else return '' end end local function color2lum(c) if (c == nil) then return '' end -- html '#' entity c = c:gsub("&#35;", "#") -- whitespace c = c:match( '^%s*(.-)[%s;]*$' ) -- unstrip nowiki strip markers c = mw.text.unstripNoWiki(c) -- lowercase c = c:lower() -- first try to look it up local L = HTMLcolor[c] if (L ~= nil) then return L end -- convert from hsl if mw.ustring.match(c,'^hsl%([%s]*[0-9][0-9%.]*[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then local h, s, l = mw.ustring.match(c,'^hsl%([%s]*([0-9][0-9%.]*)[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$') return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100) end -- convert from rgb if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*%)$') then local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*%)$') return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B)) end -- convert from rgb percent if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$') return rgbdec2lum(255*tonumber(R)/100, 255*tonumber(G)/100, 255*tonumber(B)/100) end -- remove leading # (if there is one) and whitespace c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$') -- split into rgb local cs = mw.text.split(c or '', '') if( #cs == 6 ) then local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2]) local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4]) local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6]) return rgbdec2lum(R, G, B) elseif ( #cs == 3 ) then local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1]) local G = 16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2]) local B = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3]) return rgbdec2lum(R, G, B) end -- failure, return blank return '' end -- This exports the function for use in other modules. -- The colour is passed as a string. function p._lum(color) return color2lum(color) end function p._greatercontrast(args) local bias = tonumber(args['bias'] or '0') or 0 local css = (args['css'] and args['css'] ~= '') and true or false local v1 = color2lum(args[1] or '') local c2 = args[2] or '#FFFFFF' local v2 = color2lum(c2) local c3 = args[3] or '#000000' local v3 = color2lum(c3) local ratio1 = -1; local ratio2 = -1; if (type(v1) == 'number' and type(v2) == 'number') then ratio1 = (v2 + 0.05)/(v1 + 0.05) ratio1 = (ratio1 < 1) and 1/ratio1 or ratio1 end if (type(v1) == 'number' and type(v3) == 'number') then ratio2 = (v3 + 0.05)/(v1 + 0.05) ratio2 = (ratio2 < 1) and 1/ratio2 or ratio2 end if css then local c1 = args[1] or '' if mw.ustring.match(c1, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') or mw.ustring.match(c1, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') then c1 = '#' .. c1 end if mw.ustring.match(c2, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') or mw.ustring.match(c2, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') then c2 = '#' .. c2 end if mw.ustring.match(v3, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') or mw.ustring.match(v3, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]$') then c3 = '#' .. c3 end return 'background-color:' .. c1 .. '; color:' .. ((ratio1 > 0) and (ratio2 > 0) and ((ratio1 + bias > ratio2) and c2 or c3) or '') .. ';' end return (ratio1 > 0) and (ratio2 > 0) and ((ratio1 + bias > ratio2) and c2 or c3) or '' end function p._ratio(args) local v1 = color2lum(args[1]) local v2 = color2lum(args[2]) if (type(v1) == 'number' and type(v2) == 'number') then -- v1 should be the brighter of the two. if v2 > v1 then v1, v2 = v2, v1 end return (v1 + 0.05)/(v2 + 0.05) else return args['error'] or '?' end end function p._styleratio(args) local style = (args[1] or ''):lower() local bg, fg = 'white', 'black' local lum_bg, lum_fg = 1, 0 if args[2] then local lum = color2lum(args[2]) if lum ~= '' then bg, lum_bg = args[2], lum end end if args[3] then local lum = color2lum(args[3]) if lum ~= '' then fg, lum_fg = args[3], lum end end local slist = mw.text.split(mw.ustring.gsub(mw.ustring.gsub(style or '', '&#[Xx]23;', '#'), '&#35;', '#'), ';') for k = 1,#slist do local s = slist[k] local k,v = s:match( '^[%s]*([^:]-):([^:]-)[%s;]*$' ) k = k or '' v = v or '' if (k:match('^[%s]*(background)[%s]*$') or k:match('^[%s]*(background%-color)[%s]*$')) then local lum = color2lum(v) if( lum ~= '' ) then bg, lum_bg = v, lum end elseif (k:match('^[%s]*(color)[%s]*$')) then local lum = color2lum(v) if( lum ~= '' ) then bg, lum_fg = v, lum end end end if lum_bg > lum_fg then return (lum_bg + 0.05)/(lum_fg + 0.05) else return (lum_fg + 0.05)/(lum_bg + 0.05) end end --[[ Use {{#invoke:Color contrast|somecolor}} directly or {{#invoke:Color contrast}} from a wrapper template. Parameters: -- |1= — required; A color to check. --]] function p.lum(frame) local color = frame.args[1] or frame:getParent().args[1] return p._lum(color) end function p.ratio(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._ratio(args) end function p.styleratio(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._styleratio(args) end function p.greatercontrast(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._greatercontrast(args) end return p 1e399769117591366a63f62996c9a407077cc711 มอดูล:Color contrast/colors 828 87 169 2023-10-05T17:14:29Z PeachFullzZ 2 สร้างหน้าด้วย "return { aliceblue = 0.92880068253475, antiquewhite = 0.84646951707754, aqua = 0.7874, aquamarine = 0.8078549208338, azure = 0.97265264954166, beige = 0.8988459998705, bisque = 0.80732327372979, black = 0, blanchedalmond = 0.85084439608156, blue = 0.0722, blueviolet = 0.12622014321946, brown..." Scribunto text/plain return { aliceblue = 0.92880068253475, antiquewhite = 0.84646951707754, aqua = 0.7874, aquamarine = 0.8078549208338, azure = 0.97265264954166, beige = 0.8988459998705, bisque = 0.80732327372979, black = 0, blanchedalmond = 0.85084439608156, blue = 0.0722, blueviolet = 0.12622014321946, brown = 0.098224287876511, burlywood = 0.51559844533893, cadetblue = 0.29424681085422, chartreuse = 0.76032025902623, chocolate = 0.23898526114557, coral = 0.37017930872924, cornflowerblue = 0.30318641994179, cornsilk = 0.93562110372965, crimson = 0.16042199953026, cyan = 0.7874, darkblue = 0.018640801980939, darkcyan = 0.20329317839046, darkgoldenrod = 0.27264703559993, darkgray = 0.39675523072563, darkgreen = 0.091143429047575, darkgrey = 0.39675523072563, darkkhaki = 0.45747326349994, darkmagenta = 0.07353047651207, darkolivegreen = 0.12651920884889, darkorange = 0.40016167026524, darkorchid = 0.13413142174857, darkred = 0.054889674531132, darksalmon = 0.40541471563381, darkseagreen = 0.43789249325969, darkslateblue = 0.065792846227988, darkslategray = 0.067608151928044, darkslategrey = 0.067608151928044, darkturquoise = 0.4874606277449, darkviolet = 0.10999048339343, deeppink = 0.23866895828276, deepskyblue = 0.44481603395575, dimgray = 0.14126329114027, dimgrey = 0.14126329114027, dodgerblue = 0.27442536991456, firebrick = 0.10724525535015, floralwhite = 0.95922484825004, forestgreen = 0.18920812076002, fuchsia = 0.2848, gainsboro = 0.71569350050648, ghostwhite = 0.94311261886323, gold = 0.69860877428159, goldenrod = 0.41919977809569, gray = 0.2158605001139, green = 0.15438342968146, greenyellow = 0.80609472611453, grey = 0.2158605001139, honeydew = 0.96336535554782, hotpink = 0.34658438169715, indianred = 0.21406134963884, indigo = 0.03107561486337, ivory = 0.99071270600615, khaki = 0.77012343394121, lavender = 0.80318750514521, lavenderblush = 0.90172748631046, lawngreen = 0.73905893124963, lemonchiffon = 0.94038992245622, lightblue = 0.63709141280807, lightcoral = 0.35522120733135, lightcyan = 0.94587293494829, lightgoldenrodyellow = 0.93348351018297, lightgray = 0.65140563741982, lightgreen = 0.69091979956865, lightgrey = 0.65140563741982, lightpink = 0.58566152734898, lightsalmon = 0.4780675225206, lightseagreen = 0.35050145117042, lightskyblue = 0.56195637618331, lightslategray = 0.23830165007287, lightslategrey = 0.23830165007287, lightsteelblue = 0.53983888284666, lightyellow = 0.98161818392882, lime = 0.7152, limegreen = 0.44571042246098, linen = 0.88357340984379, magenta = 0.2848, maroon = 0.045891942324215, mediumaquamarine = 0.49389703310801, mediumblue = 0.044077780212328, mediumorchid = 0.21639251153773, mediumpurple = 0.22905858091648, mediumseagreen = 0.34393112338131, mediumslateblue = 0.20284629471622, mediumspringgreen = 0.70704308194184, mediumturquoise = 0.5133827926448, mediumvioletred = 0.14371899849357, midnightblue = 0.02071786635086, mintcream = 0.97834604947588, mistyrose = 0.82183047859185, moccasin = 0.80083000991567, navajowhite = 0.76519682342785, navy = 0.015585128108224, oldlace = 0.91900633405549, olive = 0.20027537200568, olivedrab = 0.22593150951929, orange = 0.4817026703631, orangered = 0.25516243753416, orchid = 0.31348806761439, palegoldenrod = 0.78792647887614, palegreen = 0.77936759006353, paleturquoise = 0.76436077921714, palevioletred = 0.28754994117889, papayawhip = 0.87797100199835, peachpuff = 0.74905589878251, peru = 0.30113074877936, pink = 0.63271070702466, plum = 0.45734221587969, powderblue = 0.68254586500605, purple = 0.061477070432439, rebeccapurple = 0.07492341159447, red = 0.2126, rosybrown = 0.32319457649407, royalblue = 0.16663210743188, saddlebrown = 0.097922285020521, salmon = 0.36977241527596, sandybrown = 0.46628543696283, seagreen = 0.19734199706275, seashell = 0.92737862206922, sienna = 0.13697631337098, silver = 0.52711512570581, skyblue = 0.55291668518184, slateblue = 0.14784278062136, slategray = 0.20896704076536, slategrey = 0.20896704076536, snow = 0.96533341834849, springgreen = 0.73052306068529, steelblue = 0.20562642207625, tan = 0.48237604163921, teal = 0.16996855778968, thistle = 0.56818401093733, tomato = 0.30638612719415, turquoise = 0.5895536427578, violet = 0.40315452986676, wheat = 0.74909702820482, white = 1, whitesmoke = 0.91309865179342, yellow = 0.9278, yellowgreen = 0.50762957208707, } 6ae47fdb24de4eed5ec26d203faf5341a388987b 170 169 2023-10-05T17:14:40Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Color contrast/colors]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain return { aliceblue = 0.92880068253475, antiquewhite = 0.84646951707754, aqua = 0.7874, aquamarine = 0.8078549208338, azure = 0.97265264954166, beige = 0.8988459998705, bisque = 0.80732327372979, black = 0, blanchedalmond = 0.85084439608156, blue = 0.0722, blueviolet = 0.12622014321946, brown = 0.098224287876511, burlywood = 0.51559844533893, cadetblue = 0.29424681085422, chartreuse = 0.76032025902623, chocolate = 0.23898526114557, coral = 0.37017930872924, cornflowerblue = 0.30318641994179, cornsilk = 0.93562110372965, crimson = 0.16042199953026, cyan = 0.7874, darkblue = 0.018640801980939, darkcyan = 0.20329317839046, darkgoldenrod = 0.27264703559993, darkgray = 0.39675523072563, darkgreen = 0.091143429047575, darkgrey = 0.39675523072563, darkkhaki = 0.45747326349994, darkmagenta = 0.07353047651207, darkolivegreen = 0.12651920884889, darkorange = 0.40016167026524, darkorchid = 0.13413142174857, darkred = 0.054889674531132, darksalmon = 0.40541471563381, darkseagreen = 0.43789249325969, darkslateblue = 0.065792846227988, darkslategray = 0.067608151928044, darkslategrey = 0.067608151928044, darkturquoise = 0.4874606277449, darkviolet = 0.10999048339343, deeppink = 0.23866895828276, deepskyblue = 0.44481603395575, dimgray = 0.14126329114027, dimgrey = 0.14126329114027, dodgerblue = 0.27442536991456, firebrick = 0.10724525535015, floralwhite = 0.95922484825004, forestgreen = 0.18920812076002, fuchsia = 0.2848, gainsboro = 0.71569350050648, ghostwhite = 0.94311261886323, gold = 0.69860877428159, goldenrod = 0.41919977809569, gray = 0.2158605001139, green = 0.15438342968146, greenyellow = 0.80609472611453, grey = 0.2158605001139, honeydew = 0.96336535554782, hotpink = 0.34658438169715, indianred = 0.21406134963884, indigo = 0.03107561486337, ivory = 0.99071270600615, khaki = 0.77012343394121, lavender = 0.80318750514521, lavenderblush = 0.90172748631046, lawngreen = 0.73905893124963, lemonchiffon = 0.94038992245622, lightblue = 0.63709141280807, lightcoral = 0.35522120733135, lightcyan = 0.94587293494829, lightgoldenrodyellow = 0.93348351018297, lightgray = 0.65140563741982, lightgreen = 0.69091979956865, lightgrey = 0.65140563741982, lightpink = 0.58566152734898, lightsalmon = 0.4780675225206, lightseagreen = 0.35050145117042, lightskyblue = 0.56195637618331, lightslategray = 0.23830165007287, lightslategrey = 0.23830165007287, lightsteelblue = 0.53983888284666, lightyellow = 0.98161818392882, lime = 0.7152, limegreen = 0.44571042246098, linen = 0.88357340984379, magenta = 0.2848, maroon = 0.045891942324215, mediumaquamarine = 0.49389703310801, mediumblue = 0.044077780212328, mediumorchid = 0.21639251153773, mediumpurple = 0.22905858091648, mediumseagreen = 0.34393112338131, mediumslateblue = 0.20284629471622, mediumspringgreen = 0.70704308194184, mediumturquoise = 0.5133827926448, mediumvioletred = 0.14371899849357, midnightblue = 0.02071786635086, mintcream = 0.97834604947588, mistyrose = 0.82183047859185, moccasin = 0.80083000991567, navajowhite = 0.76519682342785, navy = 0.015585128108224, oldlace = 0.91900633405549, olive = 0.20027537200568, olivedrab = 0.22593150951929, orange = 0.4817026703631, orangered = 0.25516243753416, orchid = 0.31348806761439, palegoldenrod = 0.78792647887614, palegreen = 0.77936759006353, paleturquoise = 0.76436077921714, palevioletred = 0.28754994117889, papayawhip = 0.87797100199835, peachpuff = 0.74905589878251, peru = 0.30113074877936, pink = 0.63271070702466, plum = 0.45734221587969, powderblue = 0.68254586500605, purple = 0.061477070432439, rebeccapurple = 0.07492341159447, red = 0.2126, rosybrown = 0.32319457649407, royalblue = 0.16663210743188, saddlebrown = 0.097922285020521, salmon = 0.36977241527596, sandybrown = 0.46628543696283, seagreen = 0.19734199706275, seashell = 0.92737862206922, sienna = 0.13697631337098, silver = 0.52711512570581, skyblue = 0.55291668518184, slateblue = 0.14784278062136, slategray = 0.20896704076536, slategrey = 0.20896704076536, snow = 0.96533341834849, springgreen = 0.73052306068529, steelblue = 0.20562642207625, tan = 0.48237604163921, teal = 0.16996855778968, thistle = 0.56818401093733, tomato = 0.30638612719415, turquoise = 0.5895536427578, violet = 0.40315452986676, wheat = 0.74909702820482, white = 1, whitesmoke = 0.91309865179342, yellow = 0.9278, yellowgreen = 0.50762957208707, } 6ae47fdb24de4eed5ec26d203faf5341a388987b แม่แบบ:Nowrap 10 88 176 2023-10-06T04:27:50Z PeachFullzZ 2 สร้างหน้าด้วย "<span class="nowrap">{{{1}}}</span><noinclude> {{documentation}} <!-- Categories go on the /doc page; interwikis go to Wikidata. --> </noinclude>" wikitext text/x-wiki <span class="nowrap">{{{1}}}</span><noinclude> {{documentation}} <!-- Categories go on the /doc page; interwikis go to Wikidata. --> </noinclude> 5d0dc6b6d89b37f4356242404f46138a4017f015 177 176 2023-10-06T04:28:17Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Nowrap]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki <span class="nowrap">{{{1}}}</span><noinclude> {{documentation}} <!-- Categories go on the /doc page; interwikis go to Wikidata. --> </noinclude> 5d0dc6b6d89b37f4356242404f46138a4017f015 อานุภาพ คุณูปจางบริรักษ์ 0 89 178 2023-10-06T04:49:50Z PeachFullzZ 2 สร้างหน้าด้วย "{{กล่องข้อมูล ผู้ดำรงตำแหน่ง | honorific-suffix = ม.ป.ช., ม.ว.ม., ต.จ.ว., บ.ภ. | roblox_username = NOOBGAMERTH009 | image = | imagesize = | caption = | office = นายกรัฐมนตรีไทย | order = คนที่ 1 | deputy = | term_start = 13 พฤศจิกายน พ.ศ. 2560<br/>({{อายุปีและวัน|2017|11|13}}) | term_end..." wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | honorific-suffix = ม.ป.ช., ม.ว.ม., ต.จ.ว., บ.ภ. | roblox_username = NOOBGAMERTH009 | image = | imagesize = | caption = | office = นายกรัฐมนตรีไทย | order = คนที่ 1 | deputy = | term_start = 13 พฤศจิกายน พ.ศ. 2560<br/>({{อายุปีและวัน|2017|11|13}}) | term_end = | subterm = พระประมุข | suboffice = [[พระบาทสมเด็จพระปรมินทรมหาตะวันธิราชรามาธิบดี]]<br/>[[เนติวิทย์ นวโชติ|พระประมุขเจ้าเนติวิชญานันต์ พระชัยราชประมุข]]<br/>[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] | predecessor = | successor = | birth_date = | birth_place = [[กรุงเทพมหานคร]] [[ประเทศไทย]] | party = [[พรรคประชาธิปัตย์|ประชาธิปัตย์]] (2565–ปัจจุบัน) | occupation = [[นักการเมือง]] | signature = }} '''อานุภาพ คุณูปจางบริรักษ์''' เป็นนักการเมืองชาวไทย นายกรัฐมนตรีคนแรกของ[[ประเทศไทย]] ซึ่งดำรงตำแหน่งตั้งแต่วันที่ 13 พฤศจิกายน พ.ศ. 2560 และเป็นหัวหน้า[[คณะรักษาอานุภาพแห่งชาติ]] นำ[[รัฐประหารในประเทศไทย พ.ศ. 2564|การรัฐประหาร พ.ศ. 2564]] ซึ่งเป็นการรัฐประหารตนเอง เพื่อกำจัดกลุ่มอำนาจนิยมในขณะนั้น == งานการเมือง == == เครื่องมุขยอิสริยาภรณ์ == == อ้างอิง == {{รายการอ้างอิง}} fd832db41248bf4a3c00d6cbc96695e640e6d6f3 179 178 2023-10-06T04:52:45Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | honorific-suffix = ม.ป.ช., ม.ว.ม., ต.จ.ว., บ.ภ. | roblox_username = NOOBGAMERTH009 | image = | imagesize = | caption = | office = นายกรัฐมนตรีไทย | order = คนที่ 1 | deputy = | term_start = 13 พฤศจิกายน พ.ศ. 2560<br/>({{อายุปีและวัน|2017|11|13}}) | term_end = | subterm = พระประมุข | suboffice = [[พระบาทสมเด็จพระปรมินทรมหาตะวันธิราชรามาธิบดี]]<br/>[[เนติวิทย์ นวโชติ|พระประมุขเจ้าเนติวิชญานันต์ พระชัยราชประมุข]]<br/>[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] | predecessor = | successor = | office1 = [[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start1 = 16 กรกฎาคม พ.ศ. 2566<br/>({{อายุปีและวัน|2023|07|16}}) | term_end1 = | birth_date = | birth_place = [[กรุงเทพมหานคร]] [[ประเทศไทย]] | party = [[พรรคประชาธิปัตย์|ประชาธิปัตย์]] (2565–ปัจจุบัน) | occupation = [[นักการเมือง]] | signature = }} '''อานุภาพ คุณูปจางบริรักษ์''' เป็นนักการเมืองชาวไทย นายกรัฐมนตรีคนแรกของ[[ประเทศไทย]] ซึ่งดำรงตำแหน่งตั้งแต่วันที่ 13 พฤศจิกายน พ.ศ. 2560 [[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สมาชิกสภานิติบัญญัติแห่งชาติ]] และเป็นหัวหน้า[[คณะรักษาอานุภาพแห่งชาติ]] นำ[[รัฐประหารในประเทศไทย พ.ศ. 2564|การรัฐประหาร พ.ศ. 2564]] ซึ่งเป็นการรัฐประหารตนเอง เพื่อกำจัดกลุ่มอำนาจนิยมในขณะนั้น == งานการเมือง == == เครื่องมุขยอิสริยาภรณ์ == == อ้างอิง == {{รายการอ้างอิง}} a26d3b56d1343a72fa9de8f3c688636c58ad9729 สรายุทธ โครตอตร 0 90 181 2023-10-06T10:49:47Z PeachFullzZ 2 สร้างหน้าด้วย "{{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = MIRAKLEmodel0 | image = | imagesize = | caption = | office1 = | term_start1 = | term_end1 = | office2 = สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สมาชิกสภานิติบัญญัติแห่งชาต..." wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = MIRAKLEmodel0 | image = | imagesize = | caption = | office1 = | term_start1 = | term_end1 = | office2 = [[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start2 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | parliamentarygroup2 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office3 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = 3 ตุลาคม พ.ศ. 2566<br/>({{อายุปีและวัน|2023|10|03}}) | termend3 = | predecessor3 = [[อนาวิน สุขเกษมอดิศักดิ์]] | successor3 = | birth_date = | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[อนุญาโตตุลาการ]]<br/>[[นักการเมือง]] }} '''สรายุทธ โครตอตร''' ชื่อเล่น '''มิก''' เป็นนักการเมืองชาวไทย หัวหน้าพรรคและผู้ร่วมก่อตั้ง[[พรรคสมัยใหม่]] เขาเคยเป็นหนึ่งในตุลาการใน[[ศาลมกุฎพิเศษเฉพาะกิจ]] ในฐานะ[[อนุญาโตตุลาการ]]ที่ได้ถูกรับเชิญให้มาร่วมตัดสินพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] ในกรณีเกี่ยวกับคุณสมบัติการเป็นพระประมุขตามรัฐธรรมนูญและกฎมณเฑียรบาล f0f5286b98c995721c508561dd4156c89051d254 แม่แบบ:กล่องคำพูด 10 3 183 3 2023-10-06T11:24:14Z PeachFullzZ 2 wikitext text/x-wiki <templatestyles src="แม่แบบ:Quote box/styles.css" /><div class="quotebox pullquote {{#switch: {{lc:{{{align|}}}}} | center = centered | left = floatleft | none = | floatright }} {{{class|}}}" style=" {{#if:{{{width|}}} |width:{{{width}}};}} {{#ifeq:{{{border}}}|none|border:none;|{{#if:{{{border|}}}|border-width: {{{border}}}}};}} {{#if:{{{fontsize|}}}|font-size: {{{fontsize}}};}} {{#if:{{{bgcolor|}}}|background-color: {{#ifeq:{{{bgcolor|}}}|none|transparent|{{{bgcolor}}}}};}} {{{style|}}}"> {{#if:{{{title|}}} |<div class="quotebox-title {{{tclass|}}}" style=" {{#if:{{{title_bg|{{{bgcolor|}}}}}}|background-color: {{#ifeq:{{{title_bg|{{{bgcolor}}}}}}|none|transparent|{{{title_bg|{{{bgcolor}}}}}}}};}} {{#if:{{{title_fnt|}}}|color: {{{title_fnt}}};}} {{{tstyle|}}}">{{{title}}}</div> }} <blockquote class="quotebox-quote {{main other||{{#if:{{{quoted|}}}|quoted}}}} {{#switch: {{lc:{{{qalign|{{{halign|left}}}}}}}} |right = right-aligned |center = center-aligned |left-aligned }} {{{qclass|}}}" style=" {{{qstyle|}}}"> {{{text|{{{content|{{{quotetext|{{{quote|{{{1|<includeonly>{{error|ข้อผิดพลาด: ไม่มีข้อความในการทำกล่องคำพูด (หรือเครื่องหมายเท่ากับที่ใช้ในอาร์กิวเมนต์จริงจะถูกเข้าใจว่าเป็นพารามิเตอร์ที่ไม่มีชื่อ)}}</includeonly><noinclude>{{lorem ipsum}}</noinclude>}}}}}}}}}}}}}}} </blockquote> {{#if:{{{author|{{{source|}}}}}}{{{2|}}}{{{3|}}}|<cite class="{{#switch: {{lc:{{{salign|{{{qalign|{{{halign|left}}} }}} }}} }} |right = right-aligned |center = center-aligned |left-aligned }}" style="{{{sstyle|}}}"><!--ต้องลบเครื่องหมายขีดกลางที่แทรกอยู่ด้วยตนเอง ออกจากการใช้แม่แบบ จากนั้นจึงเปิดใช้งาน:--><!--—&thinsp;-->{{{author|{{{2|}}}}}}{{#if:{{{author|}}}{{{2|}}}|{{#if:{{{source|}}}{{{3|}}}|<!--แสดงเครื่องหมายจุลภาค-เว้นวรรค เฉพาะเมื่อมีพารามิเตอร์อ้างอิงทั้งสองรายการเท่านั้น-->,&#32;}}}}{{{source|{{{3|}}}}}}</cite>}} </div>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[หมวดหมู่:หน้าที่ใช้กล่องคำพูดซึ่งมีพารามิเตอร์ที่ไม่รู้จัก|_VALUE_{{PAGENAME}}]]}}|preview=หน้าที่ใช้ [[แม่แบบ:กล่องคำพูด]] ซึ่งมีพารามิเตอร์ที่ไม่รู้จัก "_VALUE_"|ignoreblank=y| 1 | 2 | 3 | align | author | bgcolor | border | class | content | fontsize | halign | qalign | qclass | qstyle | quote | quoted | quotetext | salign | source | sstyle | style | tclass | text | title | title_bg | title_fnt | tstyle | width }}<noinclude> {{เอกสารประกอบ}} </noinclude> 6658c3190b9f3003527c75b0478a510ae5a0301d แม่แบบ:Quote box/styles.css 10 91 184 2023-10-06T11:26:32Z PeachFullzZ 2 สร้างหน้าด้วย "/* {{pp-template}} */ .quotebox { background-color: #F9F9F9; border: 1px solid #aaa; box-sizing: border-box; padding: 10px; font-size: 88%; max-width: 100%; } .quotebox.floatleft { margin: .5em 1.4em .8em 0; } .quotebox.floatright { margin: .5em 0 .8em 1.4em; } .quotebox.centered { overflow: hidden; position: relative; margin: .5em auto .8em auto; } .quotebox.floatleft span, .quotebox.floatright span { font-style: inherit; } .quotebox >..." sanitized-css text/css /* {{pp-template}} */ .quotebox { background-color: #F9F9F9; border: 1px solid #aaa; box-sizing: border-box; padding: 10px; font-size: 88%; max-width: 100%; } .quotebox.floatleft { margin: .5em 1.4em .8em 0; } .quotebox.floatright { margin: .5em 0 .8em 1.4em; } .quotebox.centered { overflow: hidden; position: relative; margin: .5em auto .8em auto; } .quotebox.floatleft span, .quotebox.floatright span { font-style: inherit; } .quotebox > blockquote { margin: 0; padding: 0; /* Styling from Minerva */ border-left: 0; font-family: inherit; font-size: inherit; } .quotebox-title { background-color: #F9F9F9; text-align: center; font-size: 110%; font-weight: bold; } .quotebox-quote > :first-child { margin-top: 0; } .quotebox-quote:last-child > :last-child { margin-bottom: 0; } .quotebox-quote.quoted:before { font-family:'Times New Roman',serif; font-weight:bold; font-size: large; color: gray; content: ' “ '; vertical-align: -45%; line-height: 0; } .quotebox-quote.quoted:after { font-family:'Times New Roman',serif; font-weight:bold; font-size: large; color: gray; content: ' ” '; line-height: 0; } .quotebox .left-aligned { text-align: left; } .quotebox .right-aligned { text-align: right; } .quotebox .center-aligned { text-align: center; } .quotebox .quote-title, .quotebox .quotebox-quote { display: block; } .quotebox cite { display:block; font-style:normal; } @media screen and (max-width:640px) { .quotebox { /*override inline styles */ width: 100% !important; margin: 0 0 .8em !important; float: none !important; } } c6ed92a92ff9774be727e66a8b57231cb39829ff อนาวิน สุขเกษมอดิศักดิ์ 0 2 185 125 2023-10-06T11:27:59Z PeachFullzZ 2 /* สมาชิกสภานิติบัญญัติแห่งชาติ */ wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = Anavin Sukkasem-Adisak (2 August 2023).png | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[ศาลรัฐธรรมนูญ|ตุลาการศาลรัฐธรรมนูญ]] | term_start1 = 1 พฤศจิกายน พ.ศ. 2565 | term_end1 = 10 พฤษภาคม พ.ศ. 2566<br>({{อายุปีและวัน|2022|11|1|2023|5|10}}) | office2 = [[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start2 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | parliamentarygroup2 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office3 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = 16 พฤษภาคม | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2023|5|16|2023|9|20}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 ต่อมาอนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า {{กล่องคำพูด | quote = "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" | source =—อนาวิน สุขเกษมอดิศักดิ์<ref>ไทยเอ็นบีซี [@ThaiNBC]. (3 สิงหาคม 2566). ''[https://twitter.com/ThaiNBC/status/1686795068479590400 ประโยคเด็ด อนาวิน สุขเกษมอดิศักดิ์ ตอบคำถามประชาชน ภายหลังจาก แถลงข่าวเปิดพรรคสมัยใหม่]''. [ทวิต]. ทวิตเตอร์ (X).</ref> | align = left | width = 250px }} === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ<ref>เดอะ พีชเชอร์ [@thepeacherco]. (20 กันยายน 2566). ''[https://twitter.com/thepeacherco/status/1704415771441660174 อนาวิน หัวหน้าพรรคสมัยใหม่ โพสต์ลาออกจากตำแหน่ง 'หัวหน้าพรรค' อย่างเป็นทางการ พร้อมทิ้งท้าย "อิอิ"]''. [ทวิต]. ทวิตเตอร์ (X).</ref> ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย == อ้างอิง == {{รายการอ้างอิง}} edb30a3f75bf61922d0493b7568c2bb9d78ea20b 188 185 2023-10-06T11:46:30Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = Anavin Sukkasem-Adisak (2 August 2023).png | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[ศาลรัฐธรรมนูญ|ตุลาการศาลรัฐธรรมนูญ]] | term_start1 = 1 พฤศจิกายน พ.ศ. 2565 | term_end1 = 10 พฤษภาคม พ.ศ. 2566<br>({{อายุปีและวัน|2022|11|1|2023|5|10}}) | office2 = [[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start2 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | parliamentarygroup2 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office3 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = 16 พฤษภาคม | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2023|5|16|2023|9|20}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 === พรรคสมัยใหม่ === [[ไฟล์:Modern Forward Party Launch Press Conference 2 August 2023.png|left|250px|thumb| อนาวินและกรรมการบริหารพรรคแถลงข่าวเปิดตัวพรรคสมัยใหม่เมื่อวันที่ 2 สิงหาคม พ.ศ. 2566]] อนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า {{กล่องคำพูด | quote = "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" | source =—อนาวิน สุขเกษมอดิศักดิ์<ref>ไทยเอ็นบีซี [@ThaiNBC]. (3 สิงหาคม 2566). ''[https://twitter.com/ThaiNBC/status/1686795068479590400 ประโยคเด็ด อนาวิน สุขเกษมอดิศักดิ์ ตอบคำถามประชาชน ภายหลังจาก แถลงข่าวเปิดพรรคสมัยใหม่]''. [ทวิต]. ทวิตเตอร์ (X).</ref> | align = left | width = 250px }} === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ<ref>เดอะ พีชเชอร์ [@thepeacherco]. (20 กันยายน 2566). ''[https://twitter.com/thepeacherco/status/1704415771441660174 อนาวิน หัวหน้าพรรคสมัยใหม่ โพสต์ลาออกจากตำแหน่ง 'หัวหน้าพรรค' อย่างเป็นทางการ พร้อมทิ้งท้าย "อิอิ"]''. [ทวิต]. ทวิตเตอร์ (X).</ref> ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย == อ้างอิง == {{รายการอ้างอิง}} 9e981ce55c82c9d6824a78d7a61ae4cf3dd0358e 189 188 2023-10-06T11:50:03Z PeachFullzZ 2 /* พรรคสมัยใหม่ */ wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = Anavin Sukkasem-Adisak (2 August 2023).png | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[ศาลรัฐธรรมนูญ|ตุลาการศาลรัฐธรรมนูญ]] | term_start1 = 1 พฤศจิกายน พ.ศ. 2565 | term_end1 = 10 พฤษภาคม พ.ศ. 2566<br>({{อายุปีและวัน|2022|11|1|2023|5|10}}) | office2 = [[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start2 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | parliamentarygroup2 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office3 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = 16 พฤษภาคม | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2023|5|16|2023|9|20}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === อนาวินได้ก้าวเข้าสู่วงการการเมืองด้วยการถูกแต่งตั้งให้เป็นสมาชิกสภานิติบัญญัติแห่งชาติ เมื่อวันที่ 16 กรกฎาคม 2566 === พรรคสมัยใหม่ === [[ไฟล์:Modern Forward Party Launch Press Conference 2 August 2023.png|left|250px|thumb| อนาวินและกรรมการบริหารพรรคแถลงข่าวเปิดตัวพรรคสมัยใหม่เมื่อวันที่ 2 สิงหาคม พ.ศ. 2566]] อนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ<ref>ไทยเอ็นบีซี [@ThaiNBC]. (2 สิงหาคม 2566). ''[https://twitter.com/ThaiNBC/status/1686747656125874176 อนาวิน เปิดตัว พรรคสมัยใหม่ ชูวิสัยทัศน์ Advance Education เปลี่ยนไทยสู่สมัยใหม่]''. [ทวิต]. ทวิตเตอร์ (X).</ref> ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า {{กล่องคำพูด | quote = "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" | source =—อนาวิน สุขเกษมอดิศักดิ์<ref>ไทยเอ็นบีซี [@ThaiNBC]. (3 สิงหาคม 2566). ''[https://twitter.com/ThaiNBC/status/1686795068479590400 ประโยคเด็ด อนาวิน สุขเกษมอดิศักดิ์ ตอบคำถามประชาชน ภายหลังจาก แถลงข่าวเปิดพรรคสมัยใหม่]''. [ทวิต]. ทวิตเตอร์ (X).</ref> | align = left | width = 250px }} === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ<ref>เดอะ พีชเชอร์ [@thepeacherco]. (20 กันยายน 2566). ''[https://twitter.com/thepeacherco/status/1704415771441660174 อนาวิน หัวหน้าพรรคสมัยใหม่ โพสต์ลาออกจากตำแหน่ง 'หัวหน้าพรรค' อย่างเป็นทางการ พร้อมทิ้งท้าย "อิอิ"]''. [ทวิต]. ทวิตเตอร์ (X).</ref> ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย == อ้างอิง == {{รายการอ้างอิง}} 4ed87af7731feaf4ac520d24c06cc945ee804883 191 189 2023-10-06T12:07:14Z PeachFullzZ 2 /* งานการเมือง */ wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = Anavin Sukkasem-Adisak (2 August 2023).png | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[ศาลรัฐธรรมนูญ|ตุลาการศาลรัฐธรรมนูญ]] | term_start1 = 1 พฤศจิกายน พ.ศ. 2565 | term_end1 = 10 พฤษภาคม พ.ศ. 2566<br>({{อายุปีและวัน|2022|11|1|2023|5|10}}) | office2 = [[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start2 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | parliamentarygroup2 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office3 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = 16 พฤษภาคม | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2023|5|16|2023|9|20}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล|ท่านชายอชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === [[ไฟล์:Thai MP Standing and Talking.png|left|250px|thumb|อนาวินขณะยืนคุยกับสมาชิกสภานิติบัญญัติแห่งชาติ]] อนาวินได้ก้าวเข้าสู่แวดวงการเมือง จากการมีพระประมุขบัญชาแต่งตั้งเป็นสมาชิก[[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สภานิติบัญญัติแห่งชาติ]] เมื่อวันที่ 16 กรกฎาคม 2566 ซึ่งมีผู้ได้รับการแต่งตั้งจำนวน 16 คน โดยอนาวินได้ถูกจัดให้อยู่ในกลุ่มอาชีพนักการเมือง ซึ่งมาจากพรรคสมัยใหม่ === พรรคสมัยใหม่ === [[ไฟล์:Modern Forward Party Launch Press Conference 2 August 2023.png|left|250px|thumb| อนาวินและกรรมการบริหารพรรคแถลงข่าวเปิดตัวพรรคสมัยใหม่เมื่อวันที่ 2 สิงหาคม พ.ศ. 2566]] อนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ<ref>ไทยเอ็นบีซี [@ThaiNBC]. (2 สิงหาคม 2566). ''[https://twitter.com/ThaiNBC/status/1686747656125874176 อนาวิน เปิดตัว พรรคสมัยใหม่ ชูวิสัยทัศน์ Advance Education เปลี่ยนไทยสู่สมัยใหม่]''. [ทวิต]. ทวิตเตอร์ (X).</ref> ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า {{กล่องคำพูด | quote = "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" | source =—อนาวิน สุขเกษมอดิศักดิ์<ref>ไทยเอ็นบีซี [@ThaiNBC]. (3 สิงหาคม 2566). ''[https://twitter.com/ThaiNBC/status/1686795068479590400 ประโยคเด็ด อนาวิน สุขเกษมอดิศักดิ์ ตอบคำถามประชาชน ภายหลังจาก แถลงข่าวเปิดพรรคสมัยใหม่]''. [ทวิต]. ทวิตเตอร์ (X).</ref> | align = left | width = 250px }} === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ<ref>เดอะ พีชเชอร์ [@thepeacherco]. (20 กันยายน 2566). ''[https://twitter.com/thepeacherco/status/1704415771441660174 อนาวิน หัวหน้าพรรคสมัยใหม่ โพสต์ลาออกจากตำแหน่ง 'หัวหน้าพรรค' อย่างเป็นทางการ พร้อมทิ้งท้าย "อิอิ"]''. [ทวิต]. ทวิตเตอร์ (X).</ref> ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย == อ้างอิง == {{รายการอ้างอิง}} 8d4ec9308cb03d1c5da0669cda42ae01e153926d 192 191 2023-10-06T16:17:19Z PeachFullzZ 2 wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = Anavin Sukkasem-Adisak (2 August 2023).png | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[ศาลรัฐธรรมนูญ|ตุลาการศาลรัฐธรรมนูญ]] | term_start1 = 1 พฤศจิกายน พ.ศ. 2565 | term_end1 = 10 พฤษภาคม พ.ศ. 2566<br>({{อายุปีและวัน|2022|11|1|2023|5|10}}) | office2 = [[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start2 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | parliamentarygroup2 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office3 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = 16 พฤษภาคม | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2023|5|16|2023|9|20}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === [[ไฟล์:Thai MP Standing and Talking.png|left|250px|thumb|อนาวินขณะยืนคุยกับสมาชิกสภานิติบัญญัติแห่งชาติ]] อนาวินได้ก้าวเข้าสู่แวดวงการเมือง จากการมีพระประมุขบัญชาแต่งตั้งเป็นสมาชิก[[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สภานิติบัญญัติแห่งชาติ]] เมื่อวันที่ 16 กรกฎาคม 2566 ซึ่งมีผู้ได้รับการแต่งตั้งจำนวน 16 คน โดยอนาวินได้ถูกจัดให้อยู่ในกลุ่มอาชีพนักการเมือง ซึ่งมาจากพรรคสมัยใหม่ === พรรคสมัยใหม่ === [[ไฟล์:Modern Forward Party Launch Press Conference 2 August 2023.png|left|250px|thumb| อนาวินและกรรมการบริหารพรรคแถลงข่าวเปิดตัวพรรคสมัยใหม่เมื่อวันที่ 2 สิงหาคม พ.ศ. 2566]] อนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ<ref>ไทยเอ็นบีซี [@ThaiNBC]. (2 สิงหาคม 2566). ''[https://twitter.com/ThaiNBC/status/1686747656125874176 อนาวิน เปิดตัว พรรคสมัยใหม่ ชูวิสัยทัศน์ Advance Education เปลี่ยนไทยสู่สมัยใหม่]''. [ทวิต]. ทวิตเตอร์ (X).</ref> ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า {{กล่องคำพูด | quote = "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" | source =—อนาวิน สุขเกษมอดิศักดิ์<ref>ไทยเอ็นบีซี [@ThaiNBC]. (3 สิงหาคม 2566). ''[https://twitter.com/ThaiNBC/status/1686795068479590400 ประโยคเด็ด อนาวิน สุขเกษมอดิศักดิ์ ตอบคำถามประชาชน ภายหลังจาก แถลงข่าวเปิดพรรคสมัยใหม่]''. [ทวิต]. ทวิตเตอร์ (X).</ref> | align = left | width = 250px }} === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ<ref>เดอะ พีชเชอร์ [@thepeacherco]. (20 กันยายน 2566). ''[https://twitter.com/thepeacherco/status/1704415771441660174 อนาวิน หัวหน้าพรรคสมัยใหม่ โพสต์ลาออกจากตำแหน่ง 'หัวหน้าพรรค' อย่างเป็นทางการ พร้อมทิ้งท้าย "อิอิ"]''. [ทวิต]. ทวิตเตอร์ (X).</ref> ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย == อ้างอิง == {{รายการอ้างอิง}} 2e5935a9e967e0dadce67f81cfee088d09aafb15 193 192 2023-10-06T16:27:07Z PeachFullzZ 2 /* สมาชิกสภานิติบัญญัติแห่งชาติ */ wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = dustsavagezzz | image = Anavin Sukkasem-Adisak (2 August 2023).png | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[ศาลรัฐธรรมนูญ|ตุลาการศาลรัฐธรรมนูญ]] | term_start1 = 1 พฤศจิกายน พ.ศ. 2565 | term_end1 = 10 พฤษภาคม พ.ศ. 2566<br>({{อายุปีและวัน|2022|11|1|2023|5|10}}) | office2 = [[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start2 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | parliamentarygroup2 = กลุ่มนักการเมือง ([[พรรคสมัยใหม่]]) (2566–ปัจจุบัน) | office3 = [[พรรคสมัยใหม่|หัวหน้าพรรคสมัยใหม่]] | termstart3 = 16 พฤษภาคม | termend3 = 20 กันยายน พ.ศ. 2566<br>({{อายุปีและวัน|2023|5|16|2023|9|20}}) | successor3 = [[สรายุทธ โครตอตร]] | birth_date = | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = [[พรรคสมัยใหม่|สมัยใหม่]] (2566–ปัจจุบัน) | occupation = [[นักการเมือง]] }} '''อนาวิน สุขเกษมอดิศักดิ์''' เป็นนักการเมืองชาวไทย สมาชิก[[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สภานิติบัญญัติแห่งชาติ]] อดีตตุลาการ[[ศาลรัฐธรรมนูญ]] และอดีตหัวหน้า[[พรรคสมัยใหม่]] เขาเริ่มเป็นที่รู้จักในแวดวงการเมืองจากการแถลงข่าวจัดตั้งพรรคสมัยใหม่ โดยชูนโยบาย "Advance Education" และเป็นที่รู้จักจากการอภิปรายในรัฐสภา ภายใต้การนำของอนาวิน พรรคสมัยใหม่ได้กลายเป็นพรรคการเมืองที่ใหญ่ที่สุด จากการมีสมาชิกสังกัดพรรคเป็นจำนวนมาก ซึ่งมากกว่าพรรคอื่น ๆ ที่มีอยู่ใน[[ประเทศไทย]] == รับราชการ == อนาวินได้ถูกแต่งตั้งให้เป็นตุลาการศาลรัฐธรรมนูญ และได้ถูกเชิญให้เป็นองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ ในการวินิจฉัยพระคดีของ[[พระประมุขเจ้าปุณณภพปรเมศ พระชัยราชประมุข]] พระประมุขที่ 3 ในกรณีเกี่ยวกับคุณสมบัติในการเป็น[[ประมุขแห่งรัฐ]] ว่าทรงมีคุณสมบัติครบถ้วนหรือไม่ โดยศาลได้มีคำพิพากษาว่าพระประมุขเจ้าปุณณภพปรเมศ ทรงมีคุณสมบัติไม่ครบถ้วนตามกฎมณเฑียรบาล ที่มีเจตนารมณ์ให้ผู้สืบมุขยสมบัติเป็นผู้นับถือศาสนาพุทธ แต่พระองค์ทรงนับถือศาสนาคริสต์ หลังจากนั้นไม่นาน อนาวินจึงได้ลาออกจากตำแหน่งตุลาการศาลรัฐธรรมนูญ เนื่องจากต้องการทำงานด้านการเมือง ต่อมาเมื่อมีการแต่งตั้ง[[อชิระ กาญจนสกุล]] ให้เป็นผู้สำเร็จราชการแทนพระประมุข อนาวินในฐานะที่เคยเป็นตุลาการศาลรัฐธรรมนูญเพียงคนเดียว และเป็นหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ จึงได้ถูกเชิญให้ไปเป็นประธานสักขีพยานในการให้สัตย์ปฏิญาณของผู้สำเร็จราชการ โดยเป็นประธานร่วมกับ[[เนติวิทย์ นวโชติ]] ประธานศาลฎีกาและหนึ่งในองค์คณะในศาลมกุฎพิเศษเฉพาะกิจ และ[[อานุภาพ คุณูปจางบริรักษ์]] นายกรัฐมนตรี ณ พระที่นั่งฑิฆัมพรฯ พระราชวังดุสิต เมื่อวันที่ 8 กรกฎาคม 2566 == งานการเมือง == === สมาชิกสภานิติบัญญัติแห่งชาติ === [[ไฟล์:Thai MP Standing and Talking.png|left|250px|thumb|อนาวินขณะยืนคุยกับสมาชิกสภานิติบัญญัติแห่งชาติ]] อนาวินได้ก้าวเข้าสู่การเมือง จากการมีพระประมุขบัญชาแต่งตั้งเป็นสมาชิก[[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สภานิติบัญญัติแห่งชาติ]] เมื่อวันที่ 16 กรกฎาคม 2566 ซึ่งมีผู้ได้รับการแต่งตั้งจำนวน 16 คน โดยอนาวินได้ถูกจัดให้อยู่ในกลุ่มอาชีพนักการเมือง ซึ่งมาจากพรรคสมัยใหม่ === พรรคสมัยใหม่ === [[ไฟล์:Modern Forward Party Launch Press Conference 2 August 2023.png|left|250px|thumb| อนาวินและกรรมการบริหารพรรคแถลงข่าวเปิดตัวพรรคสมัยใหม่เมื่อวันที่ 2 สิงหาคม พ.ศ. 2566]] อนาวินได้ก่อตั้งพรรคการเมืองร่วมกับสมาชิกพรรคหลายคน มีชื่อว่า "พรรคสมัยใหม่" โดยมีอุดมการณ์ประชาธิปไตยเสรีนิยมก้าวหน้า ในการแถลงข่าวจัดตั้งพรรคสมัยใหม่ อนาวินได้ชูนโยบาย Advance Education ที่จะให้มีการจัดสร้างการศึกษาขั้นสูงภายในประเทศอย่างมีประสิทธิภาพ<ref>ไทยเอ็นบีซี [@ThaiNBC]. (2 สิงหาคม 2566). ''[https://twitter.com/ThaiNBC/status/1686747656125874176 อนาวิน เปิดตัว พรรคสมัยใหม่ ชูวิสัยทัศน์ Advance Education เปลี่ยนไทยสู่สมัยใหม่]''. [ทวิต]. ทวิตเตอร์ (X).</ref> ทำให้เป็นที่สนใจของคนในสังคมเป็นอย่างมาก โดยในการแถลง อนาวินได้มีการกล่าวอย่างหนักแน่นว่า {{กล่องคำพูด | quote = "ถ้าผมทำตามนโยบายของผม ที่ผมตั้งขึ้นมาเองไม่ได้ ผมจะลาออกจากพรรคสมัยใหม่… และผมจะเลิกเล่นการเมืองตลอดชีวิต คนอย่างอนาวินไม่มีวันคืนคำครับ" | source =—อนาวิน สุขเกษมอดิศักดิ์<ref>ไทยเอ็นบีซี [@ThaiNBC]. (3 สิงหาคม 2566). ''[https://twitter.com/ThaiNBC/status/1686795068479590400 ประโยคเด็ด อนาวิน สุขเกษมอดิศักดิ์ ตอบคำถามประชาชน ภายหลังจาก แถลงข่าวเปิดพรรคสมัยใหม่]''. [ทวิต]. ทวิตเตอร์ (X).</ref> | align = left | width = 250px }} === การเลือกนายกรัฐมนตรีและการลาออก === อนาวินถูกจับตาในทางการเมืองเป็นอย่างมาก โดยมีการคาดการณ์ว่าจะเป็นแคนดิเดตนายกรัฐมนตรีของพรรคสมัยใหม่ ร่วมกับ[[สรายุทธ โครตอตร]] รองหัวหน้าพรรค และ[[เบญจา วรรณศิริลักษณ์]] กรรมการบริหารพรรค แต่ปรากฎว่าไม่เคยมีการประกาศหรือมีการเสนอชื่อทั้งสามคนอย่างเป็นทางการจากพรรคสมัยใหม่หรือในสภานิติบัญญติแห่งชาติเลย ในท้ายที่สุดสภาได้มีการเสนอชื่ออานุภาพ คุณูปจางบริรักษ์ และ[[จุทาเทพยศะมหรนะ ธาราวัชรจินดา]] รองประธานกรรมการ[[บริษัท เครือตั้งหวังเจ๊ง จำกัด]] เป็นนายกรัฐมนตรี ซึ่งในการอภิปรายคุณสมบัติ อนาวินและสมาชิกพรรคต่างพูดเชิงสนับสนุนจุทาเทพฯ ให้เป็นนายกรัฐมนตรี ก่อนที่ในวันลงมติเลือกนายกรัฐมนตรีจะลงมติเลือกอานุภาพ คุณูปจางบริรักษ์ ให้เป็นนายกรัฐมนตรีอีกสมัย ในวันที่ 20 กันยายน 2566 อนาวินได้ประกาศลาออกจากตำแหน่งหัวหน้าพรรคสมัยใหม่อย่างเป็นทางการ<ref>เดอะ พีชเชอร์ [@thepeacherco]. (20 กันยายน 2566). ''[https://twitter.com/thepeacherco/status/1704415771441660174 อนาวิน หัวหน้าพรรคสมัยใหม่ โพสต์ลาออกจากตำแหน่ง 'หัวหน้าพรรค' อย่างเป็นทางการ พร้อมทิ้งท้าย "อิอิ"]''. [ทวิต]. ทวิตเตอร์ (X).</ref> ซึ่งก่อนหน้านั้นได้มีข่าวว่าอนาวินเตรียมลาออกตั้งแต่วันที่ 16 กันยายน แต่มีความไม่ชัดเจนว่าลาออกแล้วหรือไม่ และลาออกจากสมาชิกสภานิติบัญญัติแห่งชาติด้วยหรือไม่อย่างไร จนอนาวินได้โพสต์ข้อความลงในดิสคอร์ดอย่างเป็นทางการ ซึ่งอนาวินไม่ได้ลาออกจากการเป็นสมาชิกสภานิติบัญญัติแห่งชาติด้วย == อ้างอิง == {{รายการอ้างอิง}} 52b768b7a1e59e5e637622cb9782fa4514457780 ไฟล์:Modern Forward Party Launch Press Conference 2 August 2023.png 6 92 186 2023-10-06T11:40:42Z PeachFullzZ 2 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 187 186 2023-10-06T11:41:37Z PeachFullzZ 2 PeachFullzZ ย้ายหน้า [[ไฟล์:Move Forward Party Launch Press Conference 2 August 2023.png]] ไปยัง [[ไฟล์:Modern Forward Party Launch Press Conference 2 August 2023.png]] โดยไม่สร้างหน้าเปลี่ยนทางตามมา: ใช้ชื่อไฟล์ผิด wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 ไฟล์:Thai MP Standing and Talking.png 6 93 190 2023-10-06T12:01:36Z PeachFullzZ 2 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 วอลเตอร์ ธาราวัชรจินดา 0 94 194 2023-10-06T16:52:47Z PeachFullzZ 2 สร้างหน้าด้วย "{{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = Foxtrot_Bravo480 | image = | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start1..." wikitext text/x-wiki {{กล่องข้อมูล ผู้ดำรงตำแหน่ง | roblox_username = Foxtrot_Bravo480 | image = | imagesize = 200px | caption = อนาวิน ใน พ.ศ. 2566 | office1 = [[สภานิติบัญญัติแห่งชาติ พ.ศ. 2566|สมาชิกสภานิติบัญญัติแห่งชาติ]] | term_start1 = 16 กรกฎาคม พ.ศ. 2566<br>({{อายุปีและวัน|2023|07|16}}) | parliamentarygroup1 = กลุ่มนักธุรกิจ ([[บริษัท เครือตั้งหวังเจ๊ง จำกัด]]) (2566–ปัจจุบัน) | birth_date = | birth_place = [[กรุงเทพมหานคร]] ประเทศไทย | party = | occupation = [[นักธุรกิจ]] }} '''วอลเตอร์ ธาราวัชรจินดา''' a34901e18d8f36ea61b938be840bcbe3b92ce99a มอดูล:If empty 828 95 195 2023-10-06T17:00:08Z PeachFullzZ 2 สร้างหน้าด้วย "local p = {} function p.main(frame) local args = require('Module:Arguments').getArgs(frame, {wrappers = 'Template:If empty', removeBlanks = false}) for k,v in ipairs(args) do if v ~= '' then return v end end end return p" Scribunto text/plain local p = {} function p.main(frame) local args = require('Module:Arguments').getArgs(frame, {wrappers = 'Template:If empty', removeBlanks = false}) for k,v in ipairs(args) do if v ~= '' then return v end end end return p 4790391408957dea3ff9f453834c05f6b379a45c 196 195 2023-10-06T17:00:22Z PeachFullzZ 2 ป้องกัน "[[มอดูล:If empty]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local p = {} function p.main(frame) local args = require('Module:Arguments').getArgs(frame, {wrappers = 'Template:If empty', removeBlanks = false}) for k,v in ipairs(args) do if v ~= '' then return v end end end return p 4790391408957dea3ff9f453834c05f6b379a45c มอดูล:Unicode data 828 96 197 2023-10-06T17:08:37Z PeachFullzZ 2 สร้างหน้าด้วย "local p = {} local floor = math.floor local function errorf(level, ...) if type(level) == "number" then return error(string.format(...), level + 1) else -- level is actually the format string. return error(string.format(level, ...), 2) end end local function binary_range_search(codepoint, ranges) local low, mid, high low, high = 1, ranges.length or require "Module:TableTools".length(ranges) while low <= high do mid = floor((low + high..." Scribunto text/plain local p = {} local floor = math.floor local function errorf(level, ...) if type(level) == "number" then return error(string.format(...), level + 1) else -- level is actually the format string. return error(string.format(level, ...), 2) end end local function binary_range_search(codepoint, ranges) local low, mid, high low, high = 1, ranges.length or require "Module:TableTools".length(ranges) while low <= high do mid = floor((low + high) / 2) local range = ranges[mid] if codepoint < range[1] then high = mid - 1 elseif codepoint <= range[2] then return range, mid else low = mid + 1 end end return nil, mid end p.binary_range_search = binary_range_search --[[ local function linear_range_search(codepoint, ranges) for i, range in ipairs(ranges) do if range[1] <= codepoint and codepoint <= range[2] then return range end end end --]] -- Load a module by indexing "loader" with the name of the module minus the -- "Module:Unicode data/" part. For instance, loader.blocks returns -- [[Module:Unicode data/blocks]]. If a module cannot be loaded, false will be -- returned. local loader = setmetatable({}, { __index = function (self, key) local success, data = pcall(mw.loadData, "Module:Unicode data/" .. key) if not success then data = false end self[key] = data return data end }) -- For the algorithm used to generate Hangul Syllable names, -- see "Hangul Syllable Name Generation" in section 3.12 of the -- Unicode Specification: -- https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf local name_hooks = { { 0x00, 0x1F, "<control-%04X>" }, -- C0 control characters { 0x7F, 0x9F, "<control-%04X>" }, -- DEL and C1 control characters { 0x3400, 0x4DBF, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension A { 0x4E00, 0x9FFF, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph { 0xAC00, 0xD7A3, function (codepoint) -- Hangul Syllables local Hangul_data = loader.Hangul local syllable_index = codepoint - 0xAC00 return ("HANGUL SYLLABLE %s%s%s"):format( Hangul_data.leads[floor(syllable_index / Hangul_data.final_count)], Hangul_data.vowels[floor((syllable_index % Hangul_data.final_count) / Hangul_data.trail_count)], Hangul_data.trails[syllable_index % Hangul_data.trail_count] ) end }, -- High Surrogates, High Private Use Surrogates, Low Surrogates { 0xD800, 0xDFFF, "<surrogate-%04X>" }, { 0xE000, 0xF8FF, "<private-use-%04X>" }, -- Private Use -- CJK Compatibility Ideographs { 0xF900, 0xFA6D, "CJK COMPATIBILITY IDEOGRAPH-%04X" }, { 0xFA70, 0xFAD9, "CJK COMPATIBILITY IDEOGRAPH-%04X" }, { 0x17000, 0x187F7, "TANGUT IDEOGRAPH-%04X" }, -- Tangut Ideograph { 0x18800, 0x18AFF, function (codepoint) return ("TANGUT COMPONENT-%03d"):format(codepoint - 0x187FF) end }, { 0x18D00, 0x18D08, "TANGUT IDEOGRAPH-%04X" }, -- Tangut Ideograph Supplement { 0x1B170, 0x1B2FB, "NUSHU CHARACTER-%04X" }, -- Nushu { 0x20000, 0x2A6DF, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension B { 0x2A700, 0x2B739, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension C { 0x2B740, 0x2B81D, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension D { 0x2B820, 0x2CEA1, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension E { 0x2CEB0, 0x2EBE0, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension F -- CJK Compatibility Ideographs Supplement (Supplementary Ideographic Plane) { 0x2F800, 0x2FA1D, "CJK COMPATIBILITY IDEOGRAPH-%04X" }, { 0xE0100, 0xE01EF, function (codepoint) -- Variation Selectors Supplement return ("VARIATION SELECTOR-%d"):format(codepoint - 0xE0100 + 17) end}, { 0x30000, 0x3134A, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension G { 0x31350, 0x323AF, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension H { 0x2EBF0, 0x2EE5D, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension I { 0xF0000, 0xFFFFD, "<private-use-%04X>" }, -- Plane 15 Private Use { 0x100000, 0x10FFFD, "<private-use-%04X>" } -- Plane 16 Private Use } name_hooks.length = #name_hooks local name_range_cache local function generate_name(data, codepoint) if type(data) == "string" then return data:format(codepoint) else return data(codepoint) end end --[[ -- Checks that the code point is a number and in range. -- Does not check whether code point is an integer. -- Not used local function check_codepoint(funcName, argIdx, val) require 'libraryUtil'.checkType(funcName, argIdx, val, 'number') if codepoint < 0 or 0x10FFFF < codepoint then errorf("Codepoint %04X out of range", codepoint) end end --]] -- https://www.unicode.org/versions/Unicode11.0.0/ch04.pdf, section 4.8 function p.lookup_name(codepoint) -- U+FDD0-U+FDEF and all code points ending in FFFE or FFFF are Unassigned -- (Cn) and specifically noncharacters: -- https://www.unicode.org/faq/private_use.html#nonchar4 if 0xFDD0 <= codepoint and (codepoint <= 0xFDEF or floor(codepoint % 0x10000) >= 0xFFFE) then return ("<noncharacter-%04X>"):format(codepoint) end if name_range_cache -- Check if previously used "name hook" applies to this code point. and codepoint >= name_range_cache[1] and codepoint <= name_range_cache[2] then return generate_name(name_range_cache[3], codepoint) end local range = binary_range_search(codepoint, name_hooks) if range then name_range_cache = range return generate_name(range[3], codepoint) end local data = loader[('names/%03X'):format(codepoint / 0x1000)] if data and data[codepoint] then return data[codepoint] -- Unassigned (Cn) consists of noncharacters and reserved characters. -- The character has been established not to be a noncharacter, -- and if it were assigned, its name would already been retrieved, -- so it must be reserved. else return ("<reserved-%04X>"):format(codepoint) end end --[[ -- No image data modules on Wikipedia yet. function p.lookup_image(codepoint) local data = loader[('images/%03X'):format(codepoint / 0x1000)] if data then return data[codepoint] end end --]] local planes = { [ 0] = "Basic Multilingual Plane"; [ 1] = "Supplementary Multilingual Plane"; [ 2] = "Supplementary Ideographic Plane"; [ 3] = "Tertiary Ideographic Plane"; [14] = "Supplementary Special-purpose Plane"; [15] = "Supplementary Private Use Area-A"; [16] = "Supplementary Private Use Area-B"; } -- Load [[Module:Unicode data/blocks]] if needed and assign it to this variable. local blocks local function block_iter(blocks, i) i = i + 1 local data = blocks[i] if data then -- Unpack doesn't work on tables loaded with mw.loadData. return i, data[1], data[2], data[3] end end -- An ipairs-type iterator generator for the list of blocks. function p.enum_blocks() local blocks = loader.blocks return block_iter, blocks, 0 end function p.lookup_plane(codepoint) local i = floor(codepoint / 0x10000) return planes[i] or ("Plane %u"):format(i) end function p.lookup_block(codepoint) local blocks = loader.blocks local range = binary_range_search(codepoint, blocks) if range then return range[3] else return "No Block" end end function p.get_block_info(name) for i, block in ipairs(loader.blocks) do if block[3] == name then return block end end end function p.is_valid_pagename(pagename) local has_nonws = false for cp in mw.ustring.gcodepoint(pagename) do if (cp == 0x0023) -- # or (cp == 0x005B) -- [ or (cp == 0x005D) -- ] or (cp == 0x007B) -- { or (cp == 0x007C) -- | or (cp == 0x007D) -- } or (cp == 0x180E) -- MONGOLIAN VOWEL SEPARATOR or ((cp >= 0x2000) and (cp <= 0x200A)) -- spaces in General Punctuation block or (cp == 0xFFFD) -- REPLACEMENT CHARACTER then return false end local printable, result = p.is_printable(cp) if not printable then return false end if result ~= "space-separator" then has_nonws = true end end return has_nonws end local function manual_unpack(what, from) if what[from + 1] == nil then return what[from] end local result = {} from = from or 1 for i, item in ipairs(what) do if i >= from then table.insert(result, item) end end return unpack(result) end local function compare_ranges(range1, range2) return range1[1] < range2[1] end -- Creates a function to look up data in a module that contains "singles" (a -- code point-to-data map) and "ranges" (an array containing arrays that contain -- the low and high code points of a range and the data associated with that -- range). -- "loader" loads and returns the "singles" and "ranges" tables. -- "match_func" is passed the code point and either the data or the "dots", and -- generates the final result of the function. -- The varargs ("dots") describes the default data to be returned if there wasn't -- a match. -- In case the function is used more than once, "cache" saves ranges that have -- already been found to match, or a range whose data is the default if there -- was no match. local function memo_lookup(data_module_subpage, match_func, ...) local dots = { ... } local cache = {} local singles, ranges return function (codepoint) if not singles then local data_module = loader[data_module_subpage] singles, ranges = data_module.singles, data_module.ranges end if singles[codepoint] then return match_func(codepoint, singles[codepoint]) end local range = binary_range_search(codepoint, cache) if range then return match_func(codepoint, manual_unpack(range, 3)) end local range, index = binary_range_search(codepoint, ranges) if range then table.insert(cache, range) table.sort(cache, compare_ranges) return match_func(codepoint, manual_unpack(range, 3)) end if ranges[index] then local dots_range if codepoint > ranges[index][2] then dots_range = { ranges[index][2] + 1, ranges[index + 1] and ranges[index + 1][1] - 1 or 0x10FFFF, unpack(dots) } else -- codepoint < range[index][1] dots_range = { ranges[index - 1] and ranges[index - 1][2] + 1 or 0, ranges[index][1] - 1, unpack(dots) } end table.sort(cache, compare_ranges) end return match_func(codepoint) end end -- Get a code point's combining class value in [[Module:Unicode data/combining]], -- and return whether this value is not zero. Zero is assigned as the default -- if the combining class value is not found in this data module. -- That is, return true if character is combining, or false if it is not. -- See https://www.unicode.org/reports/tr44/#Canonical_Combining_Class_Values for -- more information. p.is_combining = memo_lookup( "combining", function (codepoint, combining_class) return combining_class and combining_class ~= 0 or false end, 0) function p.add_dotted_circle(str) return (mw.ustring.gsub(str, ".", function(char) if p.is_combining(mw.ustring.codepoint(char)) then return '◌' .. char end end)) end local lookup_control = memo_lookup( "control", function (codepoint, ccc) return ccc or "assigned" end, "assigned") p.lookup_control = lookup_control function p.is_assigned(codepoint) return lookup_control(codepoint) ~= "unassigned" end function p.is_printable(codepoint) local result = lookup_control(codepoint) return (result == "assigned") or (result == "space-separator"), result end function p.is_whitespace(codepoint) local result = lookup_control(codepoint) return (result == "space-separator"), result end p.lookup_category = memo_lookup( "category", function (codepoint, category) return category end, "Cn") local lookup_script = memo_lookup( "scripts", function (codepoint, script_code) return script_code or 'Zzzz' end, "Zzzz") p.lookup_script = lookup_script function p.get_best_script(str) -- Check type of argument, because mw.text.decode coerces numbers to strings! require "libraryUtil".checkType("get_best_script", 1, str, "string") -- Convert HTML character references (including named character references, -- or character entities) to characters. str = mw.text.decode(str, true) local scripts = {} for codepoint in mw.ustring.gcodepoint(str) do local script = lookup_script(codepoint) -- Ignore "Inherited", "Undetermined", or "Uncoded" scripts. if not (script == "Zyyy" or script == "Zinh" or script == "Zzzz") then scripts[script] = true end end -- If scripts does not contain two or more keys, -- return first and only key (script code) in table. if not next(scripts, next(scripts)) then return next(scripts) end -- else return majority script, or else "Zzzz"? end function p.is_Latin(str) require "libraryUtil".checkType("get_best_script", 1, str, "string") str = mw.text.decode(str, true) -- Search for the leading bytes that introduce the UTF-8 encoding of the -- code points U+0340-U+10FFFF. If they are not found and there is at least -- one Latin-script character, the string counts as Latin, because the rest -- of the characters can only be Zyyy, Zinh, and Zzzz. -- The only scripts found below U+0370 (the first code point of the Greek -- and Coptic block) are Latn, Zyyy, Zinh, and Zzzz. -- See the codepage in the [[UTF-8]] article. if not str:find "[\205-\244]" then for codepoint in mw.ustring.gcodepoint(str) do if lookup_script(codepoint) == "Latn" then return true end end end local Latn = false for codepoint in mw.ustring.gcodepoint(str) do local script = lookup_script(codepoint) if script == "Latn" then Latn = true elseif not (script == "Zyyy" or script == "Zinh" or script == "Zzzz") then return false end end return Latn end -- Checks that a string contains only characters belonging to right-to-left -- scripts, or characters of ignorable scripts. function p.is_rtl(str) require "libraryUtil".checkType("get_best_script", 1, str, "string") str = mw.text.decode(str, true) -- Search for the leading bytes that introduce the UTF-8 encoding of the -- code points U+0580-U+10FFFF. If they are not found, the string can only -- have characters from a left-to-right script, because the first code point -- in a right-to-left script is U+0591, in the Hebrew block. if not str:find "[\214-\244]" then return false end local result = false local rtl = loader.scripts.rtl for codepoint in mw.ustring.gcodepoint(str) do local script = lookup_script(codepoint) if rtl[script] then result = true elseif not (script == "Zyyy" or script == "Zinh" or script == "Zzzz") then return false end end return result end --[[--------------------------< I S _ R T L _ F R A M E >------------------------------------------------------ external entry from an {{#invoke:}} to determine if a string of text is rtl. Strips html and html-like tags so that those tags don't corrupt the is-rtl-is-not-rtl determination; this added for the cases where the rtl text has <br /> tags. ]] function p.is_rtl_frame (frame) local str = frame.args[1]; -- get the string from the {{#invoke:}} frame str = str:gsub ('%b<>', ''); -- strip any html and html-like tags return p.is_rtl (str); -- return if whatever remains rtl; false else end local function get_codepoint(args, arg) local codepoint_string = args[arg] or errorf(2, "Parameter %s is required", tostring(arg)) local codepoint = tonumber(codepoint_string, 16) or errorf(2, "Parameter %s is not a code point in hexadecimal base", tostring(arg)) if not (0 <= codepoint and codepoint <= 0x10FFFF) then errorf(2, "code point in parameter %s out of range", tostring(arg)) end return codepoint end local function get_func(args, arg, prefix) local suffix = args[arg] or errorf(2, "Parameter %s is required", tostring(arg)) suffix = mw.text.trim(suffix) local func_name = prefix .. suffix local func = p[func_name] or errorf(2, "There is no function '%s'", func_name) return func end -- This function allows any of the "lookup" functions to be invoked. The first -- parameter is the word after "lookup_"; the second parameter is the code point -- in hexadecimal base. function p.lookup(frame) local func = get_func(frame.args, 1, "lookup_") local codepoint = get_codepoint(frame.args, 2) local result = func(codepoint) if func == p.lookup_name then -- Prevent code point labels such as <control-0000> from being -- interpreted as HTML tags. result = result:gsub("<", "&lt;") end return result end function p.is(frame) local func = get_func(frame.args, 1, "is_") -- is_Latin and is_valid_pagename take strings. if func == p.is_Latin or func == p.is_valid_pagename or func == p.is_rtl then return (func(frame.args[2])) else -- The rest take code points. local codepoint = get_codepoint(frame.args, 2) return (func(codepoint)) -- Adjust to one result. end end return p 898b5f0689e2646f633acbbd08143920c87abef2 198 197 2023-10-06T17:08:51Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Unicode data]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local p = {} local floor = math.floor local function errorf(level, ...) if type(level) == "number" then return error(string.format(...), level + 1) else -- level is actually the format string. return error(string.format(level, ...), 2) end end local function binary_range_search(codepoint, ranges) local low, mid, high low, high = 1, ranges.length or require "Module:TableTools".length(ranges) while low <= high do mid = floor((low + high) / 2) local range = ranges[mid] if codepoint < range[1] then high = mid - 1 elseif codepoint <= range[2] then return range, mid else low = mid + 1 end end return nil, mid end p.binary_range_search = binary_range_search --[[ local function linear_range_search(codepoint, ranges) for i, range in ipairs(ranges) do if range[1] <= codepoint and codepoint <= range[2] then return range end end end --]] -- Load a module by indexing "loader" with the name of the module minus the -- "Module:Unicode data/" part. For instance, loader.blocks returns -- [[Module:Unicode data/blocks]]. If a module cannot be loaded, false will be -- returned. local loader = setmetatable({}, { __index = function (self, key) local success, data = pcall(mw.loadData, "Module:Unicode data/" .. key) if not success then data = false end self[key] = data return data end }) -- For the algorithm used to generate Hangul Syllable names, -- see "Hangul Syllable Name Generation" in section 3.12 of the -- Unicode Specification: -- https://www.unicode.org/versions/Unicode11.0.0/ch03.pdf local name_hooks = { { 0x00, 0x1F, "<control-%04X>" }, -- C0 control characters { 0x7F, 0x9F, "<control-%04X>" }, -- DEL and C1 control characters { 0x3400, 0x4DBF, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension A { 0x4E00, 0x9FFF, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph { 0xAC00, 0xD7A3, function (codepoint) -- Hangul Syllables local Hangul_data = loader.Hangul local syllable_index = codepoint - 0xAC00 return ("HANGUL SYLLABLE %s%s%s"):format( Hangul_data.leads[floor(syllable_index / Hangul_data.final_count)], Hangul_data.vowels[floor((syllable_index % Hangul_data.final_count) / Hangul_data.trail_count)], Hangul_data.trails[syllable_index % Hangul_data.trail_count] ) end }, -- High Surrogates, High Private Use Surrogates, Low Surrogates { 0xD800, 0xDFFF, "<surrogate-%04X>" }, { 0xE000, 0xF8FF, "<private-use-%04X>" }, -- Private Use -- CJK Compatibility Ideographs { 0xF900, 0xFA6D, "CJK COMPATIBILITY IDEOGRAPH-%04X" }, { 0xFA70, 0xFAD9, "CJK COMPATIBILITY IDEOGRAPH-%04X" }, { 0x17000, 0x187F7, "TANGUT IDEOGRAPH-%04X" }, -- Tangut Ideograph { 0x18800, 0x18AFF, function (codepoint) return ("TANGUT COMPONENT-%03d"):format(codepoint - 0x187FF) end }, { 0x18D00, 0x18D08, "TANGUT IDEOGRAPH-%04X" }, -- Tangut Ideograph Supplement { 0x1B170, 0x1B2FB, "NUSHU CHARACTER-%04X" }, -- Nushu { 0x20000, 0x2A6DF, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension B { 0x2A700, 0x2B739, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension C { 0x2B740, 0x2B81D, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension D { 0x2B820, 0x2CEA1, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension E { 0x2CEB0, 0x2EBE0, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension F -- CJK Compatibility Ideographs Supplement (Supplementary Ideographic Plane) { 0x2F800, 0x2FA1D, "CJK COMPATIBILITY IDEOGRAPH-%04X" }, { 0xE0100, 0xE01EF, function (codepoint) -- Variation Selectors Supplement return ("VARIATION SELECTOR-%d"):format(codepoint - 0xE0100 + 17) end}, { 0x30000, 0x3134A, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension G { 0x31350, 0x323AF, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension H { 0x2EBF0, 0x2EE5D, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension I { 0xF0000, 0xFFFFD, "<private-use-%04X>" }, -- Plane 15 Private Use { 0x100000, 0x10FFFD, "<private-use-%04X>" } -- Plane 16 Private Use } name_hooks.length = #name_hooks local name_range_cache local function generate_name(data, codepoint) if type(data) == "string" then return data:format(codepoint) else return data(codepoint) end end --[[ -- Checks that the code point is a number and in range. -- Does not check whether code point is an integer. -- Not used local function check_codepoint(funcName, argIdx, val) require 'libraryUtil'.checkType(funcName, argIdx, val, 'number') if codepoint < 0 or 0x10FFFF < codepoint then errorf("Codepoint %04X out of range", codepoint) end end --]] -- https://www.unicode.org/versions/Unicode11.0.0/ch04.pdf, section 4.8 function p.lookup_name(codepoint) -- U+FDD0-U+FDEF and all code points ending in FFFE or FFFF are Unassigned -- (Cn) and specifically noncharacters: -- https://www.unicode.org/faq/private_use.html#nonchar4 if 0xFDD0 <= codepoint and (codepoint <= 0xFDEF or floor(codepoint % 0x10000) >= 0xFFFE) then return ("<noncharacter-%04X>"):format(codepoint) end if name_range_cache -- Check if previously used "name hook" applies to this code point. and codepoint >= name_range_cache[1] and codepoint <= name_range_cache[2] then return generate_name(name_range_cache[3], codepoint) end local range = binary_range_search(codepoint, name_hooks) if range then name_range_cache = range return generate_name(range[3], codepoint) end local data = loader[('names/%03X'):format(codepoint / 0x1000)] if data and data[codepoint] then return data[codepoint] -- Unassigned (Cn) consists of noncharacters and reserved characters. -- The character has been established not to be a noncharacter, -- and if it were assigned, its name would already been retrieved, -- so it must be reserved. else return ("<reserved-%04X>"):format(codepoint) end end --[[ -- No image data modules on Wikipedia yet. function p.lookup_image(codepoint) local data = loader[('images/%03X'):format(codepoint / 0x1000)] if data then return data[codepoint] end end --]] local planes = { [ 0] = "Basic Multilingual Plane"; [ 1] = "Supplementary Multilingual Plane"; [ 2] = "Supplementary Ideographic Plane"; [ 3] = "Tertiary Ideographic Plane"; [14] = "Supplementary Special-purpose Plane"; [15] = "Supplementary Private Use Area-A"; [16] = "Supplementary Private Use Area-B"; } -- Load [[Module:Unicode data/blocks]] if needed and assign it to this variable. local blocks local function block_iter(blocks, i) i = i + 1 local data = blocks[i] if data then -- Unpack doesn't work on tables loaded with mw.loadData. return i, data[1], data[2], data[3] end end -- An ipairs-type iterator generator for the list of blocks. function p.enum_blocks() local blocks = loader.blocks return block_iter, blocks, 0 end function p.lookup_plane(codepoint) local i = floor(codepoint / 0x10000) return planes[i] or ("Plane %u"):format(i) end function p.lookup_block(codepoint) local blocks = loader.blocks local range = binary_range_search(codepoint, blocks) if range then return range[3] else return "No Block" end end function p.get_block_info(name) for i, block in ipairs(loader.blocks) do if block[3] == name then return block end end end function p.is_valid_pagename(pagename) local has_nonws = false for cp in mw.ustring.gcodepoint(pagename) do if (cp == 0x0023) -- # or (cp == 0x005B) -- [ or (cp == 0x005D) -- ] or (cp == 0x007B) -- { or (cp == 0x007C) -- | or (cp == 0x007D) -- } or (cp == 0x180E) -- MONGOLIAN VOWEL SEPARATOR or ((cp >= 0x2000) and (cp <= 0x200A)) -- spaces in General Punctuation block or (cp == 0xFFFD) -- REPLACEMENT CHARACTER then return false end local printable, result = p.is_printable(cp) if not printable then return false end if result ~= "space-separator" then has_nonws = true end end return has_nonws end local function manual_unpack(what, from) if what[from + 1] == nil then return what[from] end local result = {} from = from or 1 for i, item in ipairs(what) do if i >= from then table.insert(result, item) end end return unpack(result) end local function compare_ranges(range1, range2) return range1[1] < range2[1] end -- Creates a function to look up data in a module that contains "singles" (a -- code point-to-data map) and "ranges" (an array containing arrays that contain -- the low and high code points of a range and the data associated with that -- range). -- "loader" loads and returns the "singles" and "ranges" tables. -- "match_func" is passed the code point and either the data or the "dots", and -- generates the final result of the function. -- The varargs ("dots") describes the default data to be returned if there wasn't -- a match. -- In case the function is used more than once, "cache" saves ranges that have -- already been found to match, or a range whose data is the default if there -- was no match. local function memo_lookup(data_module_subpage, match_func, ...) local dots = { ... } local cache = {} local singles, ranges return function (codepoint) if not singles then local data_module = loader[data_module_subpage] singles, ranges = data_module.singles, data_module.ranges end if singles[codepoint] then return match_func(codepoint, singles[codepoint]) end local range = binary_range_search(codepoint, cache) if range then return match_func(codepoint, manual_unpack(range, 3)) end local range, index = binary_range_search(codepoint, ranges) if range then table.insert(cache, range) table.sort(cache, compare_ranges) return match_func(codepoint, manual_unpack(range, 3)) end if ranges[index] then local dots_range if codepoint > ranges[index][2] then dots_range = { ranges[index][2] + 1, ranges[index + 1] and ranges[index + 1][1] - 1 or 0x10FFFF, unpack(dots) } else -- codepoint < range[index][1] dots_range = { ranges[index - 1] and ranges[index - 1][2] + 1 or 0, ranges[index][1] - 1, unpack(dots) } end table.sort(cache, compare_ranges) end return match_func(codepoint) end end -- Get a code point's combining class value in [[Module:Unicode data/combining]], -- and return whether this value is not zero. Zero is assigned as the default -- if the combining class value is not found in this data module. -- That is, return true if character is combining, or false if it is not. -- See https://www.unicode.org/reports/tr44/#Canonical_Combining_Class_Values for -- more information. p.is_combining = memo_lookup( "combining", function (codepoint, combining_class) return combining_class and combining_class ~= 0 or false end, 0) function p.add_dotted_circle(str) return (mw.ustring.gsub(str, ".", function(char) if p.is_combining(mw.ustring.codepoint(char)) then return '◌' .. char end end)) end local lookup_control = memo_lookup( "control", function (codepoint, ccc) return ccc or "assigned" end, "assigned") p.lookup_control = lookup_control function p.is_assigned(codepoint) return lookup_control(codepoint) ~= "unassigned" end function p.is_printable(codepoint) local result = lookup_control(codepoint) return (result == "assigned") or (result == "space-separator"), result end function p.is_whitespace(codepoint) local result = lookup_control(codepoint) return (result == "space-separator"), result end p.lookup_category = memo_lookup( "category", function (codepoint, category) return category end, "Cn") local lookup_script = memo_lookup( "scripts", function (codepoint, script_code) return script_code or 'Zzzz' end, "Zzzz") p.lookup_script = lookup_script function p.get_best_script(str) -- Check type of argument, because mw.text.decode coerces numbers to strings! require "libraryUtil".checkType("get_best_script", 1, str, "string") -- Convert HTML character references (including named character references, -- or character entities) to characters. str = mw.text.decode(str, true) local scripts = {} for codepoint in mw.ustring.gcodepoint(str) do local script = lookup_script(codepoint) -- Ignore "Inherited", "Undetermined", or "Uncoded" scripts. if not (script == "Zyyy" or script == "Zinh" or script == "Zzzz") then scripts[script] = true end end -- If scripts does not contain two or more keys, -- return first and only key (script code) in table. if not next(scripts, next(scripts)) then return next(scripts) end -- else return majority script, or else "Zzzz"? end function p.is_Latin(str) require "libraryUtil".checkType("get_best_script", 1, str, "string") str = mw.text.decode(str, true) -- Search for the leading bytes that introduce the UTF-8 encoding of the -- code points U+0340-U+10FFFF. If they are not found and there is at least -- one Latin-script character, the string counts as Latin, because the rest -- of the characters can only be Zyyy, Zinh, and Zzzz. -- The only scripts found below U+0370 (the first code point of the Greek -- and Coptic block) are Latn, Zyyy, Zinh, and Zzzz. -- See the codepage in the [[UTF-8]] article. if not str:find "[\205-\244]" then for codepoint in mw.ustring.gcodepoint(str) do if lookup_script(codepoint) == "Latn" then return true end end end local Latn = false for codepoint in mw.ustring.gcodepoint(str) do local script = lookup_script(codepoint) if script == "Latn" then Latn = true elseif not (script == "Zyyy" or script == "Zinh" or script == "Zzzz") then return false end end return Latn end -- Checks that a string contains only characters belonging to right-to-left -- scripts, or characters of ignorable scripts. function p.is_rtl(str) require "libraryUtil".checkType("get_best_script", 1, str, "string") str = mw.text.decode(str, true) -- Search for the leading bytes that introduce the UTF-8 encoding of the -- code points U+0580-U+10FFFF. If they are not found, the string can only -- have characters from a left-to-right script, because the first code point -- in a right-to-left script is U+0591, in the Hebrew block. if not str:find "[\214-\244]" then return false end local result = false local rtl = loader.scripts.rtl for codepoint in mw.ustring.gcodepoint(str) do local script = lookup_script(codepoint) if rtl[script] then result = true elseif not (script == "Zyyy" or script == "Zinh" or script == "Zzzz") then return false end end return result end --[[--------------------------< I S _ R T L _ F R A M E >------------------------------------------------------ external entry from an {{#invoke:}} to determine if a string of text is rtl. Strips html and html-like tags so that those tags don't corrupt the is-rtl-is-not-rtl determination; this added for the cases where the rtl text has <br /> tags. ]] function p.is_rtl_frame (frame) local str = frame.args[1]; -- get the string from the {{#invoke:}} frame str = str:gsub ('%b<>', ''); -- strip any html and html-like tags return p.is_rtl (str); -- return if whatever remains rtl; false else end local function get_codepoint(args, arg) local codepoint_string = args[arg] or errorf(2, "Parameter %s is required", tostring(arg)) local codepoint = tonumber(codepoint_string, 16) or errorf(2, "Parameter %s is not a code point in hexadecimal base", tostring(arg)) if not (0 <= codepoint and codepoint <= 0x10FFFF) then errorf(2, "code point in parameter %s out of range", tostring(arg)) end return codepoint end local function get_func(args, arg, prefix) local suffix = args[arg] or errorf(2, "Parameter %s is required", tostring(arg)) suffix = mw.text.trim(suffix) local func_name = prefix .. suffix local func = p[func_name] or errorf(2, "There is no function '%s'", func_name) return func end -- This function allows any of the "lookup" functions to be invoked. The first -- parameter is the word after "lookup_"; the second parameter is the code point -- in hexadecimal base. function p.lookup(frame) local func = get_func(frame.args, 1, "lookup_") local codepoint = get_codepoint(frame.args, 2) local result = func(codepoint) if func == p.lookup_name then -- Prevent code point labels such as <control-0000> from being -- interpreted as HTML tags. result = result:gsub("<", "&lt;") end return result end function p.is(frame) local func = get_func(frame.args, 1, "is_") -- is_Latin and is_valid_pagename take strings. if func == p.is_Latin or func == p.is_valid_pagename or func == p.is_rtl then return (func(frame.args[2])) else -- The rest take code points. local codepoint = get_codepoint(frame.args, 2) return (func(codepoint)) -- Adjust to one result. end end return p 898b5f0689e2646f633acbbd08143920c87abef2 แม่แบบ:Plainlist/styles.css 10 97 199 2023-10-06T17:09:58Z PeachFullzZ 2 สร้างหน้าด้วย "/* {{pp-template|small=yes}} */ .plainlist ol, .plainlist ul { line-height: inherit; list-style: none; margin: 0; padding: 0; /* Reset Minerva default */ } .plainlist ol li, .plainlist ul li { margin-bottom: 0; }" sanitized-css text/css /* {{pp-template|small=yes}} */ .plainlist ol, .plainlist ul { line-height: inherit; list-style: none; margin: 0; padding: 0; /* Reset Minerva default */ } .plainlist ol li, .plainlist ul li { margin-bottom: 0; } 51706efa229ff8794c0d94f260a208e7c5e6ec30 200 199 2023-10-06T17:10:10Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Plainlist/styles.css]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) sanitized-css text/css /* {{pp-template|small=yes}} */ .plainlist ol, .plainlist ul { line-height: inherit; list-style: none; margin: 0; padding: 0; /* Reset Minerva default */ } .plainlist ol li, .plainlist ul li { margin-bottom: 0; } 51706efa229ff8794c0d94f260a208e7c5e6ec30 แม่แบบ:Plainlist 10 98 201 2023-10-06T17:10:42Z PeachFullzZ 2 สร้างหน้าด้วย "<templatestyles src="Plainlist/styles.css"/><div class="plainlist {{{class|}}}" {{#if:{{{style|}}}{{{indent|}}}|style="{{#if:{{{indent|}}}|margin-left: {{#expr:{{{indent}}}*1.6}}em;}} {{{style|}}}"}}>{{#if:{{{1|}}}| {{{1}}} </div>}}<noinclude></div> {{documentation}} </noinclude>" wikitext text/x-wiki <templatestyles src="Plainlist/styles.css"/><div class="plainlist {{{class|}}}" {{#if:{{{style|}}}{{{indent|}}}|style="{{#if:{{{indent|}}}|margin-left: {{#expr:{{{indent}}}*1.6}}em;}} {{{style|}}}"}}>{{#if:{{{1|}}}| {{{1}}} </div>}}<noinclude></div> {{documentation}} </noinclude> 582fe7098c25c1ecfc0ad32f62ecd674ebe2bdf0 202 201 2023-10-06T17:10:57Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Plainlist]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki <templatestyles src="Plainlist/styles.css"/><div class="plainlist {{{class|}}}" {{#if:{{{style|}}}{{{indent|}}}|style="{{#if:{{{indent|}}}|margin-left: {{#expr:{{{indent}}}*1.6}}em;}} {{{style|}}}"}}>{{#if:{{{1|}}}| {{{1}}} </div>}}<noinclude></div> {{documentation}} </noinclude> 582fe7098c25c1ecfc0ad32f62ecd674ebe2bdf0 แม่แบบ:Strfind short 10 99 203 2023-10-06T17:11:47Z PeachFullzZ 2 สร้างหน้าด้วย "{{#Invoke:String|find|source={{{1|}}}|{{{2}}}}}<noinclude> {{documentation}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude>" wikitext text/x-wiki {{#Invoke:String|find|source={{{1|}}}|{{{2}}}}}<noinclude> {{documentation}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude> 83f89aa33ee54a5e1320e75b557ecbb9c251203c 204 203 2023-10-06T17:11:59Z PeachFullzZ 2 ป้องกัน "[[แม่แบบ:Strfind short]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) wikitext text/x-wiki {{#Invoke:String|find|source={{{1|}}}|{{{2}}}}}<noinclude> {{documentation}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude> 83f89aa33ee54a5e1320e75b557ecbb9c251203c มอดูล:Plain text 828 100 205 2023-10-06T17:13:14Z PeachFullzZ 2 สร้างหน้าด้วย "--converts text with wikilinks to plain text, e.g "[[foo|gah]] is [[bar]]" to "gah is bar" --removes anything enclosed in tags that isn't nested, mediawiki strip markers (references etc), files, italic and bold markup require[[strict]] local p = {} function p.main(frame) local text = frame.args[1] local encode = require('Module:yesno')(frame.args.encode) return p._main(text, encode) end function p._main(text, encode) if not text then return en..." Scribunto text/plain --converts text with wikilinks to plain text, e.g "[[foo|gah]] is [[bar]]" to "gah is bar" --removes anything enclosed in tags that isn't nested, mediawiki strip markers (references etc), files, italic and bold markup require[[strict]] local p = {} function p.main(frame) local text = frame.args[1] local encode = require('Module:yesno')(frame.args.encode) return p._main(text, encode) end function p._main(text, encode) if not text then return end text = mw.text.killMarkers(text) :gsub('&nbsp;', ' ') --replace nbsp spaces with regular spaces :gsub('<br ?/?>', ', ') --replace br with commas :gsub('<span.->(.-)</span>', '%1') --remove spans while keeping text inside :gsub('<i.->(.-)</i>', '%1') --remove italics while keeping text inside :gsub('<b.->(.-)</b>', '%1') --remove bold while keeping text inside :gsub('<em.->(.-)</em>', '%1') --remove emphasis while keeping text inside :gsub('<strong.->(.-)</strong>', '%1') --remove strong while keeping text inside :gsub('<sub.->(.-)</sub>', '%1') --remove subscript markup; retain contents :gsub('<sup.->(.-)</sup>', '%1') --remove superscript markup; retain contents :gsub('<u.->(.-)</u>', '%1') --remove underline markup; retain contents :gsub('<.->.-<.->', '') --strip out remaining tags and the text inside :gsub('<.->', '') --remove any other tag markup :gsub('%[%[%s*[Ff][Ii][Ll][Ee]%s*:.-%]%]', '') --strip out files :gsub('%[%[%s*[Ii][Mm][Aa][Gg][Ee]%s*:.-%]%]', '') --strip out use of image: :gsub('%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:.-%]%]', '') --strip out categories :gsub('%[%[[^%]]-|', '') --strip out piped link text :gsub('([^%[])%[[^%[%]][^%]]-%s', '%1') --strip out external link text :gsub('^%[[^%[%]][^%]]-%s', '') --strip out external link text :gsub('[%[%]]', '') --then strip out remaining [ and ] :gsub("'''''", "") --strip out bold italic markup :gsub("'''?", "") --not stripping out '''' gives correct output for bolded text in quotes :gsub('----+', '') --remove ---- lines :gsub("^%s+", "") --strip leading :gsub("%s+$", "") --and trailing spaces :gsub("%s+", " ") --strip redundant spaces if encode then return mw.text.encode(text) else return text end end return p 8d406c43e8cf1dadf34be7d3b395f44ba4c48b75 206 205 2023-10-06T17:13:25Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Plain text]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain --converts text with wikilinks to plain text, e.g "[[foo|gah]] is [[bar]]" to "gah is bar" --removes anything enclosed in tags that isn't nested, mediawiki strip markers (references etc), files, italic and bold markup require[[strict]] local p = {} function p.main(frame) local text = frame.args[1] local encode = require('Module:yesno')(frame.args.encode) return p._main(text, encode) end function p._main(text, encode) if not text then return end text = mw.text.killMarkers(text) :gsub('&nbsp;', ' ') --replace nbsp spaces with regular spaces :gsub('<br ?/?>', ', ') --replace br with commas :gsub('<span.->(.-)</span>', '%1') --remove spans while keeping text inside :gsub('<i.->(.-)</i>', '%1') --remove italics while keeping text inside :gsub('<b.->(.-)</b>', '%1') --remove bold while keeping text inside :gsub('<em.->(.-)</em>', '%1') --remove emphasis while keeping text inside :gsub('<strong.->(.-)</strong>', '%1') --remove strong while keeping text inside :gsub('<sub.->(.-)</sub>', '%1') --remove subscript markup; retain contents :gsub('<sup.->(.-)</sup>', '%1') --remove superscript markup; retain contents :gsub('<u.->(.-)</u>', '%1') --remove underline markup; retain contents :gsub('<.->.-<.->', '') --strip out remaining tags and the text inside :gsub('<.->', '') --remove any other tag markup :gsub('%[%[%s*[Ff][Ii][Ll][Ee]%s*:.-%]%]', '') --strip out files :gsub('%[%[%s*[Ii][Mm][Aa][Gg][Ee]%s*:.-%]%]', '') --strip out use of image: :gsub('%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:.-%]%]', '') --strip out categories :gsub('%[%[[^%]]-|', '') --strip out piped link text :gsub('([^%[])%[[^%[%]][^%]]-%s', '%1') --strip out external link text :gsub('^%[[^%[%]][^%]]-%s', '') --strip out external link text :gsub('[%[%]]', '') --then strip out remaining [ and ] :gsub("'''''", "") --strip out bold italic markup :gsub("'''?", "") --not stripping out '''' gives correct output for bolded text in quotes :gsub('----+', '') --remove ---- lines :gsub("^%s+", "") --strip leading :gsub("%s+$", "") --and trailing spaces :gsub("%s+", " ") --strip redundant spaces if encode then return mw.text.encode(text) else return text end end return p 8d406c43e8cf1dadf34be7d3b395f44ba4c48b75 แม่แบบ:Delink 10 101 207 2023-10-06T17:14:33Z PeachFullzZ 2 สร้างหน้าด้วย "{{<includeonly>safesubst:</includeonly>#invoke:delink|delink}}<noinclude> {{documentation}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude>" wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:delink|delink}}<noinclude> {{documentation}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude> e570996a53fb3b25cc86a6b34cd2f990f7ebc1aa มอดูล:Delink 828 102 208 2023-10-06T17:15:16Z PeachFullzZ 2 สร้างหน้าด้วย "-- This module de-links most wikitext. require("strict") local p = {} local getArgs local function delinkReversePipeTrick(s) if s:match("^%[%[|.*[|\n]") then -- Check for newlines or multiple pipes. return s end return s:match("%[%[|(.*)%]%]") end local function delinkPipeTrick(s) -- We need to deal with colons, brackets, and commas, per [[Help:Pipe trick]]. -- First, remove the text before the first colon, if any. if s:match(":") then..." Scribunto text/plain -- This module de-links most wikitext. require("strict") local p = {} local getArgs local function delinkReversePipeTrick(s) if s:match("^%[%[|.*[|\n]") then -- Check for newlines or multiple pipes. return s end return s:match("%[%[|(.*)%]%]") end local function delinkPipeTrick(s) -- We need to deal with colons, brackets, and commas, per [[Help:Pipe trick]]. -- First, remove the text before the first colon, if any. if s:match(":") then s = s:match("%[%[.-:(.*)|%]%]") -- If there are no colons, grab all of the text apart from the square brackets and the pipe. else s = s:match("%[%[(.*)|%]%]") end -- Next up, brackets and commas. if s:match("%(.-%)$") then -- Brackets trump commas. s = s:match("(.-) ?%(.-%)$") elseif s:match(",") then -- If there are no brackets, display only the text before the first comma. s = s:match("(.-),.*$") end return s end -- Return wikilink target |wikilinks=target local function getDelinkedTarget(s) local result = s -- Deal with the reverse pipe trick. if result:match("%[%[|") then return delinkReversePipeTrick(result) end result = mw.uri.decode(result, "PATH") -- decode percent-encoded entities. Leave underscores and plus signs. result = mw.text.decode(result, true) -- decode HTML entities. -- Check for bad titles. To do this we need to find the -- title area of the link, i.e. the part before any pipes. local target_area if result:match("|") then -- Find if we're dealing with a piped link. target_area = result:match("^%[%[(.-)|.*%]%]") else target_area = result:match("^%[%[(.-)%]%]") end -- Check for bad characters. if mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") and mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") ~= "?" then return s end return target_area end local function getDelinkedLabel(s) local result = s -- Deal with the reverse pipe trick. if result:match("%[%[|") then return delinkReversePipeTrick(result) end result = mw.uri.decode(result, "PATH") -- decode percent-encoded entities. Leave underscores and plus signs. result = mw.text.decode(result, true) -- decode HTML entities. -- Check for bad titles. To do this we need to find the -- title area of the link, i.e. the part before any pipes. local target_area if result:match("|") then -- Find if we're dealing with a piped link. target_area = result:match("^%[%[(.-)|.*%]%]") else target_area = result:match("^%[%[(.-)%]%]") end -- Check for bad characters. if mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") and mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") ~= "?" then return s end -- Check for categories, interwikis, and files. local colon_prefix = result:match("%[%[(.-):.*%]%]") or "" -- Get the text before the first colon. local ns = mw.site.namespaces[colon_prefix] -- see if this is a known namespace if mw.language.isKnownLanguageTag(colon_prefix) or (ns and (ns.canonicalName == "File" or ns.canonicalName == "Category")) then return "" end -- Remove the colon if the link is using the [[Help:Colon trick]]. if result:match("%[%[:") then result = "[[" .. result:match("%[%[:(.*%]%])") end -- Deal with links using the [[Help:Pipe trick]]. if mw.ustring.match(result, "^%[%[[^|]*|%]%]") then return delinkPipeTrick(result) end -- Find the display area of the wikilink if result:match("|") then -- Find if we're dealing with a piped link. result = result:match("^%[%[.-|(.+)%]%]") -- Remove new lines from the display of multiline piped links, -- where the pipe is before the first new line. result = result:gsub("\n", "") else result = result:match("^%[%[(.-)%]%]") end return result end local function delinkURL(s) -- Assume we have already delinked internal wikilinks, and that -- we have been passed some text between two square brackets [foo]. -- If the text contains a line break it is not formatted as a URL, regardless of other content. if s:match("\n") then return s end -- Check if the text has a valid URL prefix and at least one valid URL character. local valid_url_prefixes = {"//", "http://", "https://", "ftp://", "gopher://", "mailto:", "news:", "irc://"} local url_prefix for _ ,v in ipairs(valid_url_prefixes) do if mw.ustring.match(s, '^%[' .. v ..'[^"%s].*%]' ) then url_prefix = v break end end -- Get display text if not url_prefix then return s end s = s:match("^%[" .. url_prefix .. "(.*)%]") -- Grab all of the text after the URL prefix and before the final square bracket. s = s:match('^.-(["<> ].*)') or "" -- Grab all of the text after the first URL separator character ("<> ). s = mw.ustring.match(s, "^%s*(%S.*)$") or "" -- If the separating character was a space, trim it off. local s_decoded = mw.text.decode(s, true) if mw.ustring.match(s_decoded, "%c") then return s end return s_decoded end local function delinkLinkClass(text, pattern, delinkFunction) if type(text) ~= "string" then error("Attempt to de-link non-string input.", 2) end if type(pattern) ~= "string" or mw.ustring.sub(pattern, 1, 1) ~= "^" then error('Invalid pattern detected. Patterns must begin with "^".', 2) end -- Iterate over the text string, and replace any matched text. using the -- delink function. We need to iterate character by character rather -- than just use gsub, otherwise nested links aren't detected properly. local result = "" while text ~= "" do -- Replace text using one iteration of gsub. text = mw.ustring.gsub(text, pattern, delinkFunction, 1) -- Append the left-most character to the result string. result = result .. mw.ustring.sub(text, 1, 1) text = mw.ustring.sub(text, 2, -1) end return result end function p._delink(args) local text = args[1] or "" if args.refs == "yes" then -- Remove any [[Help:Strip markers]] representing ref tags. In most situations -- this is not a good idea - only use it if you know what you are doing! text = mw.ustring.gsub(text, "UNIQ%w*%-ref%-%d*%-QINU", "") end if args.comments ~= "no" then text = text:gsub("<!%-%-.-%-%->", "") -- Remove html comments. end if args.wikilinks ~= "no" and args.wikilinks ~= "target" then -- De-link wikilinks and return the label portion of the wikilink. text = delinkLinkClass(text, "^%[%[.-%]%]", getDelinkedLabel) elseif args.wikilinks == "target" then -- De-link wikilinks and return the target portions of the wikilink. text = delinkLinkClass(text, "^%[%[.-%]%]", getDelinkedTarget) end if args.urls ~= "no" then text = delinkLinkClass(text, "^%[.-%]", delinkURL) -- De-link URLs. end if args.whitespace ~= "no" then -- Replace single new lines with a single space, but leave double new lines -- and new lines only containing spaces or tabs before a second new line. text = mw.ustring.gsub(text, "([^\n \t][ \t]*)\n([ \t]*[^\n \t])", "%1 %2") text = text:gsub("[ \t]+", " ") -- Remove extra tabs and spaces. end return text end function p.delink(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._delink(getArgs(frame, {wrappers = 'Template:Delink'})) end return p 5b8e75ac750b5d3ed76cc4158aefcd1568a6a6fd 209 208 2023-10-06T17:15:29Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Delink]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- This module de-links most wikitext. require("strict") local p = {} local getArgs local function delinkReversePipeTrick(s) if s:match("^%[%[|.*[|\n]") then -- Check for newlines or multiple pipes. return s end return s:match("%[%[|(.*)%]%]") end local function delinkPipeTrick(s) -- We need to deal with colons, brackets, and commas, per [[Help:Pipe trick]]. -- First, remove the text before the first colon, if any. if s:match(":") then s = s:match("%[%[.-:(.*)|%]%]") -- If there are no colons, grab all of the text apart from the square brackets and the pipe. else s = s:match("%[%[(.*)|%]%]") end -- Next up, brackets and commas. if s:match("%(.-%)$") then -- Brackets trump commas. s = s:match("(.-) ?%(.-%)$") elseif s:match(",") then -- If there are no brackets, display only the text before the first comma. s = s:match("(.-),.*$") end return s end -- Return wikilink target |wikilinks=target local function getDelinkedTarget(s) local result = s -- Deal with the reverse pipe trick. if result:match("%[%[|") then return delinkReversePipeTrick(result) end result = mw.uri.decode(result, "PATH") -- decode percent-encoded entities. Leave underscores and plus signs. result = mw.text.decode(result, true) -- decode HTML entities. -- Check for bad titles. To do this we need to find the -- title area of the link, i.e. the part before any pipes. local target_area if result:match("|") then -- Find if we're dealing with a piped link. target_area = result:match("^%[%[(.-)|.*%]%]") else target_area = result:match("^%[%[(.-)%]%]") end -- Check for bad characters. if mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") and mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") ~= "?" then return s end return target_area end local function getDelinkedLabel(s) local result = s -- Deal with the reverse pipe trick. if result:match("%[%[|") then return delinkReversePipeTrick(result) end result = mw.uri.decode(result, "PATH") -- decode percent-encoded entities. Leave underscores and plus signs. result = mw.text.decode(result, true) -- decode HTML entities. -- Check for bad titles. To do this we need to find the -- title area of the link, i.e. the part before any pipes. local target_area if result:match("|") then -- Find if we're dealing with a piped link. target_area = result:match("^%[%[(.-)|.*%]%]") else target_area = result:match("^%[%[(.-)%]%]") end -- Check for bad characters. if mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") and mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") ~= "?" then return s end -- Check for categories, interwikis, and files. local colon_prefix = result:match("%[%[(.-):.*%]%]") or "" -- Get the text before the first colon. local ns = mw.site.namespaces[colon_prefix] -- see if this is a known namespace if mw.language.isKnownLanguageTag(colon_prefix) or (ns and (ns.canonicalName == "File" or ns.canonicalName == "Category")) then return "" end -- Remove the colon if the link is using the [[Help:Colon trick]]. if result:match("%[%[:") then result = "[[" .. result:match("%[%[:(.*%]%])") end -- Deal with links using the [[Help:Pipe trick]]. if mw.ustring.match(result, "^%[%[[^|]*|%]%]") then return delinkPipeTrick(result) end -- Find the display area of the wikilink if result:match("|") then -- Find if we're dealing with a piped link. result = result:match("^%[%[.-|(.+)%]%]") -- Remove new lines from the display of multiline piped links, -- where the pipe is before the first new line. result = result:gsub("\n", "") else result = result:match("^%[%[(.-)%]%]") end return result end local function delinkURL(s) -- Assume we have already delinked internal wikilinks, and that -- we have been passed some text between two square brackets [foo]. -- If the text contains a line break it is not formatted as a URL, regardless of other content. if s:match("\n") then return s end -- Check if the text has a valid URL prefix and at least one valid URL character. local valid_url_prefixes = {"//", "http://", "https://", "ftp://", "gopher://", "mailto:", "news:", "irc://"} local url_prefix for _ ,v in ipairs(valid_url_prefixes) do if mw.ustring.match(s, '^%[' .. v ..'[^"%s].*%]' ) then url_prefix = v break end end -- Get display text if not url_prefix then return s end s = s:match("^%[" .. url_prefix .. "(.*)%]") -- Grab all of the text after the URL prefix and before the final square bracket. s = s:match('^.-(["<> ].*)') or "" -- Grab all of the text after the first URL separator character ("<> ). s = mw.ustring.match(s, "^%s*(%S.*)$") or "" -- If the separating character was a space, trim it off. local s_decoded = mw.text.decode(s, true) if mw.ustring.match(s_decoded, "%c") then return s end return s_decoded end local function delinkLinkClass(text, pattern, delinkFunction) if type(text) ~= "string" then error("Attempt to de-link non-string input.", 2) end if type(pattern) ~= "string" or mw.ustring.sub(pattern, 1, 1) ~= "^" then error('Invalid pattern detected. Patterns must begin with "^".', 2) end -- Iterate over the text string, and replace any matched text. using the -- delink function. We need to iterate character by character rather -- than just use gsub, otherwise nested links aren't detected properly. local result = "" while text ~= "" do -- Replace text using one iteration of gsub. text = mw.ustring.gsub(text, pattern, delinkFunction, 1) -- Append the left-most character to the result string. result = result .. mw.ustring.sub(text, 1, 1) text = mw.ustring.sub(text, 2, -1) end return result end function p._delink(args) local text = args[1] or "" if args.refs == "yes" then -- Remove any [[Help:Strip markers]] representing ref tags. In most situations -- this is not a good idea - only use it if you know what you are doing! text = mw.ustring.gsub(text, "UNIQ%w*%-ref%-%d*%-QINU", "") end if args.comments ~= "no" then text = text:gsub("<!%-%-.-%-%->", "") -- Remove html comments. end if args.wikilinks ~= "no" and args.wikilinks ~= "target" then -- De-link wikilinks and return the label portion of the wikilink. text = delinkLinkClass(text, "^%[%[.-%]%]", getDelinkedLabel) elseif args.wikilinks == "target" then -- De-link wikilinks and return the target portions of the wikilink. text = delinkLinkClass(text, "^%[%[.-%]%]", getDelinkedTarget) end if args.urls ~= "no" then text = delinkLinkClass(text, "^%[.-%]", delinkURL) -- De-link URLs. end if args.whitespace ~= "no" then -- Replace single new lines with a single space, but leave double new lines -- and new lines only containing spaces or tabs before a second new line. text = mw.ustring.gsub(text, "([^\n \t][ \t]*)\n([ \t]*[^\n \t])", "%1 %2") text = text:gsub("[ \t]+", " ") -- Remove extra tabs and spaces. end return text end function p.delink(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._delink(getArgs(frame, {wrappers = 'Template:Delink'})) end return p 5b8e75ac750b5d3ed76cc4158aefcd1568a6a6fd มอดูล:Page 828 103 210 2023-10-06T17:21:56Z PeachFullzZ 2 สร้างหน้าด้วย "local callAssert = require('Module:CallAssert') local function main(frame, field) local args, pargs = frame.args, ( frame:getParent() or {} ).args or {} local makeTitle=args.makeTitle or pargs.makeTitle local namespace=args.namespace or pargs.namespace or "" local fragment=args.fragment or pargs.fragment or "" local interwiki=args.interwiki or pargs.interwiki or "" local page=args.page or args[1] or pargs.page or pargs[1] or "" local id= ton..." Scribunto text/plain local callAssert = require('Module:CallAssert') local function main(frame, field) local args, pargs = frame.args, ( frame:getParent() or {} ).args or {} local makeTitle=args.makeTitle or pargs.makeTitle local namespace=args.namespace or pargs.namespace or "" local fragment=args.fragment or pargs.fragment or "" local interwiki=args.interwiki or pargs.interwiki or "" local page=args.page or args[1] or pargs.page or pargs[1] or "" local id= tonumber( args.id or pargs.id ) local pn = {} local title -- holds the result of the mw.title.xxx call for i = 1,9 do pn[i] = args['p'..i] or pargs['p'..i] end if not id and not mw.ustring.match( page, '%S' ) then page = nil end if id then title = callAssert(mw.title.new, 'mw.title.new', id) elseif not page then title = callAssert(mw.title.getCurrentTitle, 'getCurrentTitle') elseif makeTitle then title = callAssert(mw.title.makeTitle, 'makeTitle', namespace, page, fragment, interwiki) else title = callAssert(mw.title.new, 'mw.title.new', page, namespace) end local result = title[field] if type(result) == "function" then result = result(title, unpack(pn)) end return tostring(result or "") end -- handle all errors in main main = require('Module:Protect')(main) local p = {} -- main function does all the work local meta = {} function meta.__index(self, key) return function(frame) return main(frame, key) end end setmetatable(p, meta) function p.getContent(frame) local args, pargs = frame.args, ( frame:getParent() or {} ).args or {} local fmt = args.as or pargs.as or "pre" local text = main(frame, "getContent") fmt = mw.text.split( fmt, ", ?" ) for _, how in ipairs( fmt ) do if how == "pre" then text = table.concat{ "<pre>", text, "</pre>" } elseif how == "expand" then text = frame:preprocess(text) elseif how == "nowiki" then text = mw.text.nowiki(text) end end return text end return p 9b70f0ff53b1c20fd8667c9f3d80167653279cc4 211 210 2023-10-06T17:22:11Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Page]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local callAssert = require('Module:CallAssert') local function main(frame, field) local args, pargs = frame.args, ( frame:getParent() or {} ).args or {} local makeTitle=args.makeTitle or pargs.makeTitle local namespace=args.namespace or pargs.namespace or "" local fragment=args.fragment or pargs.fragment or "" local interwiki=args.interwiki or pargs.interwiki or "" local page=args.page or args[1] or pargs.page or pargs[1] or "" local id= tonumber( args.id or pargs.id ) local pn = {} local title -- holds the result of the mw.title.xxx call for i = 1,9 do pn[i] = args['p'..i] or pargs['p'..i] end if not id and not mw.ustring.match( page, '%S' ) then page = nil end if id then title = callAssert(mw.title.new, 'mw.title.new', id) elseif not page then title = callAssert(mw.title.getCurrentTitle, 'getCurrentTitle') elseif makeTitle then title = callAssert(mw.title.makeTitle, 'makeTitle', namespace, page, fragment, interwiki) else title = callAssert(mw.title.new, 'mw.title.new', page, namespace) end local result = title[field] if type(result) == "function" then result = result(title, unpack(pn)) end return tostring(result or "") end -- handle all errors in main main = require('Module:Protect')(main) local p = {} -- main function does all the work local meta = {} function meta.__index(self, key) return function(frame) return main(frame, key) end end setmetatable(p, meta) function p.getContent(frame) local args, pargs = frame.args, ( frame:getParent() or {} ).args or {} local fmt = args.as or pargs.as or "pre" local text = main(frame, "getContent") fmt = mw.text.split( fmt, ", ?" ) for _, how in ipairs( fmt ) do if how == "pre" then text = table.concat{ "<pre>", text, "</pre>" } elseif how == "expand" then text = frame:preprocess(text) elseif how == "nowiki" then text = mw.text.nowiki(text) end end return text end return p 9b70f0ff53b1c20fd8667c9f3d80167653279cc4 มอดูล:CallAssert 828 104 212 2023-10-06T17:22:56Z PeachFullzZ 2 สร้างหน้าด้วย "local function pack(...) return {...}, select('#', ...) end local function mapArray(func, array, count) local result = {} for i = 1, count or #array do result[i] = func(array[i]) end return result end local function quote(value) if type(value) == 'string' then return (string.gsub(string.format('%q', value), '\\\n', '\\n')) -- Outer parentheses remove second value returned by gsub end local str = tostring(value) if type(value) == 'tab..." Scribunto text/plain local function pack(...) return {...}, select('#', ...) end local function mapArray(func, array, count) local result = {} for i = 1, count or #array do result[i] = func(array[i]) end return result end local function quote(value) if type(value) == 'string' then return (string.gsub(string.format('%q', value), '\\\n', '\\n')) -- Outer parentheses remove second value returned by gsub end local str = tostring(value) if type(value) == 'table' and str ~= 'table' then return '{' .. str .. '}' end return str end local function callAssert(func, funcName, ...) local result, resultCount = pack(func(...)) if not result[1] then local args, argsCount = pack(...) args = mapArray(quote, args, argsCount) local message = mw.ustring.format( '%s(%s) failed', funcName, table.concat(args, ', ') ) error(message, 2) end return unpack(result, 1, resultCount) end return callAssert 1f6b71105b007b84f1593a11438484f1ad94f68a 213 212 2023-10-06T17:23:10Z PeachFullzZ 2 ป้องกัน "[[มอดูล:CallAssert]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local function pack(...) return {...}, select('#', ...) end local function mapArray(func, array, count) local result = {} for i = 1, count or #array do result[i] = func(array[i]) end return result end local function quote(value) if type(value) == 'string' then return (string.gsub(string.format('%q', value), '\\\n', '\\n')) -- Outer parentheses remove second value returned by gsub end local str = tostring(value) if type(value) == 'table' and str ~= 'table' then return '{' .. str .. '}' end return str end local function callAssert(func, funcName, ...) local result, resultCount = pack(func(...)) if not result[1] then local args, argsCount = pack(...) args = mapArray(quote, args, argsCount) local message = mw.ustring.format( '%s(%s) failed', funcName, table.concat(args, ', ') ) error(message, 2) end return unpack(result, 1, resultCount) end return callAssert 1f6b71105b007b84f1593a11438484f1ad94f68a มอดูล:High-use 828 105 214 2023-10-06T17:29:14Z PeachFullzZ 2 สร้างหน้าด้วย "local p = {} -- _fetch looks at the "demo" argument. local _fetch = require('Module:Transclusion_count').fetch local yesno = require('Module:Yesno') function p.num(frame, count) if count == nil then if yesno(frame.args['fetch']) == false then if (frame.args[1] or '') ~= '' then count = tonumber(frame.args[1]) end else count = _fetch(frame) end end -- Build output string local return_value = "" if count == nil then if frame.arg..." Scribunto text/plain local p = {} -- _fetch looks at the "demo" argument. local _fetch = require('Module:Transclusion_count').fetch local yesno = require('Module:Yesno') function p.num(frame, count) if count == nil then if yesno(frame.args['fetch']) == false then if (frame.args[1] or '') ~= '' then count = tonumber(frame.args[1]) end else count = _fetch(frame) end end -- Build output string local return_value = "" if count == nil then if frame.args[1] == "risk" then return_value = "a very large number of" else return_value = "many" end else -- Use 2 significant figures for smaller numbers and 3 for larger ones local sigfig = 2 if count >= 100000 then sigfig = 3 end -- Prepare to round to appropriate number of sigfigs local f = math.floor(math.log10(count)) - sigfig + 1 -- Round and insert "approximately" or "+" when appropriate if (frame.args[2] == "yes") or (mw.ustring.sub(frame.args[1],-1) == "+") then -- Round down return_value = string.format("%s+", mw.getContentLanguage():formatNum(math.floor( (count / 10^(f)) ) * (10^(f))) ) else -- Round to nearest return_value = string.format("approximately&#x20;%s", mw.getContentLanguage():formatNum(math.floor( (count / 10^(f)) + 0.5) * (10^(f))) ) end -- Insert percentage of pages if that is likely to be >= 1% and when |no-percent= not set to yes if count and count > 250000 and not yesno (frame:getParent().args['no-percent']) then local percent = math.floor( ( (count/frame:callParserFunction('NUMBEROFPAGES', 'R') ) * 100) + 0.5) if percent >= 1 then return_value = string.format("%s&#x20;pages, or roughly %s%% of all", return_value, percent) end end end return return_value end -- Actions if there is a large (greater than or equal to 100,000) transclusion count function p.risk(frame) local return_value = "" if frame.args[1] == "risk" then return_value = "risk" else local count = _fetch(frame) if count and count >= 100000 then return_value = "risk" end end return return_value end function p.text(frame, count) -- Only show the information about how this template gets updated if someone -- is actually editing the page and maybe trying to update the count. local bot_text = (frame:preprocess("{{REVISIONID}}") == "") and "\n\n----\n'''Preview message''': Transclusion count updated automatically ([[Template:High-use/doc#Technical details|see documentation]])." or '' if count == nil then if yesno(frame.args['fetch']) == false then if (frame.args[1] or '') ~= '' then count = tonumber(frame.args[1]) end else count = _fetch(frame) end end local title = mw.title.getCurrentTitle() if title.subpageText == "doc" or title.subpageText == "sandbox" then title = title.basePageTitle end local systemMessages = frame.args['system'] if frame.args['system'] == '' then systemMessages = nil end -- This retrieves the project URL automatically to simplify localiation. local templateCount = ('on [https://linkcount.toolforge.org/index.php?project=%s&page=%s %s pages]'):format( mw.title.getCurrentTitle():fullUrl():gsub('//(.-)/.*', '%1'), mw.uri.encode(title.fullText), p.num(frame, count)) local used_on_text = "'''This " .. (mw.title.getCurrentTitle().namespace == 828 and "Lua module" or "template") .. ' is used '; if systemMessages then used_on_text = used_on_text .. systemMessages .. ((count and count > 2000) and ("''', and " .. templateCount) or ("'''")) else used_on_text = used_on_text .. templateCount .. "'''" end local sandbox_text = ("%s's [[%s/sandbox|/sandbox]] or [[%s/testcases|/testcases]] subpages, or in your own [[%s]]. "):format( (mw.title.getCurrentTitle().namespace == 828 and "module" or "template"), title.fullText, title.fullText, mw.title.getCurrentTitle().namespace == 828 and "Module:Sandbox|module sandbox" or "Wikipedia:User pages#SUB|user subpage" ) local infoArg = frame.args["info"] ~= "" and frame.args["info"] if (systemMessages or frame.args[1] == "risk" or (count and count >= 100000) ) then local info = systemMessages and '.<br/>Changes to it can cause immediate changes to the Wikipedia user interface.' or '.' if infoArg then info = info .. "<br />" .. infoArg end sandbox_text = info .. '<br /> To avoid major disruption' .. (count and count >= 100000 and ' and server load' or '') .. ', any changes should be tested in the ' .. sandbox_text .. 'The tested changes can be added to this page in a single edit. ' else sandbox_text = (infoArg and ('.<br />' .. infoArg .. ' C') or ' and c') .. 'hanges may be widely noticed. Test changes in the ' .. sandbox_text end local discussion_text = systemMessages and 'Please discuss changes ' or 'Consider discussing changes ' if frame.args["2"] and frame.args["2"] ~= "" and frame.args["2"] ~= "yes" then discussion_text = string.format("%sat [[%s]]", discussion_text, frame.args["2"]) else discussion_text = string.format("%son the [[%s|talk page]]", discussion_text, title.talkPageTitle.fullText ) end return used_on_text .. sandbox_text .. discussion_text .. " before implementing them." .. bot_text end function p.main(frame) local count = nil if yesno(frame.args['fetch']) == false then if (frame.args[1] or '') ~= '' then count = tonumber(frame.args[1]) end else count = _fetch(frame) end local image = "[[File:Ambox warning yellow.svg|40px|alt=Warning|link=]]" local type_param = "style" local epilogue = '' if frame.args['system'] and frame.args['system'] ~= '' then image = "[[File:Ambox important.svg|40px|alt=Warning|link=]]" type_param = "content" local nocat = frame:getParent().args['nocat'] or frame.args['nocat'] local categorise = (nocat == '' or not yesno(nocat)) if categorise then epilogue = frame:preprocess('{{Sandbox other||{{#switch:{{#invoke:Effective protection level|{{#switch:{{NAMESPACE}}|File=upload|#default=edit}}|{{FULLPAGENAME}}}}|sysop|templateeditor|interfaceadmin=|#default=[[Category:Pages used in system messages needing protection]]}}}}') end elseif (frame.args[1] == "risk" or (count and count >= 100000)) then image = "[[File:Ambox warning orange.svg|40px|alt=Warning|link=]]" type_param = "content" end if frame.args["form"] == "editnotice" then return frame:expandTemplate{ title = 'editnotice', args = { ["image"] = image, ["text"] = p.text(frame, count), ["expiry"] = (frame.args["expiry"] or "") } } .. epilogue else return require('Module:Message box').main('ombox', { type = type_param, image = image, text = p.text(frame, count), expiry = (frame.args["expiry"] or "") }) .. epilogue end end return p 134551888e066954a89c109d2faa8af71a4454a4 215 214 2023-10-06T17:29:26Z PeachFullzZ 2 ป้องกัน "[[มอดูล:High-use]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local p = {} -- _fetch looks at the "demo" argument. local _fetch = require('Module:Transclusion_count').fetch local yesno = require('Module:Yesno') function p.num(frame, count) if count == nil then if yesno(frame.args['fetch']) == false then if (frame.args[1] or '') ~= '' then count = tonumber(frame.args[1]) end else count = _fetch(frame) end end -- Build output string local return_value = "" if count == nil then if frame.args[1] == "risk" then return_value = "a very large number of" else return_value = "many" end else -- Use 2 significant figures for smaller numbers and 3 for larger ones local sigfig = 2 if count >= 100000 then sigfig = 3 end -- Prepare to round to appropriate number of sigfigs local f = math.floor(math.log10(count)) - sigfig + 1 -- Round and insert "approximately" or "+" when appropriate if (frame.args[2] == "yes") or (mw.ustring.sub(frame.args[1],-1) == "+") then -- Round down return_value = string.format("%s+", mw.getContentLanguage():formatNum(math.floor( (count / 10^(f)) ) * (10^(f))) ) else -- Round to nearest return_value = string.format("approximately&#x20;%s", mw.getContentLanguage():formatNum(math.floor( (count / 10^(f)) + 0.5) * (10^(f))) ) end -- Insert percentage of pages if that is likely to be >= 1% and when |no-percent= not set to yes if count and count > 250000 and not yesno (frame:getParent().args['no-percent']) then local percent = math.floor( ( (count/frame:callParserFunction('NUMBEROFPAGES', 'R') ) * 100) + 0.5) if percent >= 1 then return_value = string.format("%s&#x20;pages, or roughly %s%% of all", return_value, percent) end end end return return_value end -- Actions if there is a large (greater than or equal to 100,000) transclusion count function p.risk(frame) local return_value = "" if frame.args[1] == "risk" then return_value = "risk" else local count = _fetch(frame) if count and count >= 100000 then return_value = "risk" end end return return_value end function p.text(frame, count) -- Only show the information about how this template gets updated if someone -- is actually editing the page and maybe trying to update the count. local bot_text = (frame:preprocess("{{REVISIONID}}") == "") and "\n\n----\n'''Preview message''': Transclusion count updated automatically ([[Template:High-use/doc#Technical details|see documentation]])." or '' if count == nil then if yesno(frame.args['fetch']) == false then if (frame.args[1] or '') ~= '' then count = tonumber(frame.args[1]) end else count = _fetch(frame) end end local title = mw.title.getCurrentTitle() if title.subpageText == "doc" or title.subpageText == "sandbox" then title = title.basePageTitle end local systemMessages = frame.args['system'] if frame.args['system'] == '' then systemMessages = nil end -- This retrieves the project URL automatically to simplify localiation. local templateCount = ('on [https://linkcount.toolforge.org/index.php?project=%s&page=%s %s pages]'):format( mw.title.getCurrentTitle():fullUrl():gsub('//(.-)/.*', '%1'), mw.uri.encode(title.fullText), p.num(frame, count)) local used_on_text = "'''This " .. (mw.title.getCurrentTitle().namespace == 828 and "Lua module" or "template") .. ' is used '; if systemMessages then used_on_text = used_on_text .. systemMessages .. ((count and count > 2000) and ("''', and " .. templateCount) or ("'''")) else used_on_text = used_on_text .. templateCount .. "'''" end local sandbox_text = ("%s's [[%s/sandbox|/sandbox]] or [[%s/testcases|/testcases]] subpages, or in your own [[%s]]. "):format( (mw.title.getCurrentTitle().namespace == 828 and "module" or "template"), title.fullText, title.fullText, mw.title.getCurrentTitle().namespace == 828 and "Module:Sandbox|module sandbox" or "Wikipedia:User pages#SUB|user subpage" ) local infoArg = frame.args["info"] ~= "" and frame.args["info"] if (systemMessages or frame.args[1] == "risk" or (count and count >= 100000) ) then local info = systemMessages and '.<br/>Changes to it can cause immediate changes to the Wikipedia user interface.' or '.' if infoArg then info = info .. "<br />" .. infoArg end sandbox_text = info .. '<br /> To avoid major disruption' .. (count and count >= 100000 and ' and server load' or '') .. ', any changes should be tested in the ' .. sandbox_text .. 'The tested changes can be added to this page in a single edit. ' else sandbox_text = (infoArg and ('.<br />' .. infoArg .. ' C') or ' and c') .. 'hanges may be widely noticed. Test changes in the ' .. sandbox_text end local discussion_text = systemMessages and 'Please discuss changes ' or 'Consider discussing changes ' if frame.args["2"] and frame.args["2"] ~= "" and frame.args["2"] ~= "yes" then discussion_text = string.format("%sat [[%s]]", discussion_text, frame.args["2"]) else discussion_text = string.format("%son the [[%s|talk page]]", discussion_text, title.talkPageTitle.fullText ) end return used_on_text .. sandbox_text .. discussion_text .. " before implementing them." .. bot_text end function p.main(frame) local count = nil if yesno(frame.args['fetch']) == false then if (frame.args[1] or '') ~= '' then count = tonumber(frame.args[1]) end else count = _fetch(frame) end local image = "[[File:Ambox warning yellow.svg|40px|alt=Warning|link=]]" local type_param = "style" local epilogue = '' if frame.args['system'] and frame.args['system'] ~= '' then image = "[[File:Ambox important.svg|40px|alt=Warning|link=]]" type_param = "content" local nocat = frame:getParent().args['nocat'] or frame.args['nocat'] local categorise = (nocat == '' or not yesno(nocat)) if categorise then epilogue = frame:preprocess('{{Sandbox other||{{#switch:{{#invoke:Effective protection level|{{#switch:{{NAMESPACE}}|File=upload|#default=edit}}|{{FULLPAGENAME}}}}|sysop|templateeditor|interfaceadmin=|#default=[[Category:Pages used in system messages needing protection]]}}}}') end elseif (frame.args[1] == "risk" or (count and count >= 100000)) then image = "[[File:Ambox warning orange.svg|40px|alt=Warning|link=]]" type_param = "content" end if frame.args["form"] == "editnotice" then return frame:expandTemplate{ title = 'editnotice', args = { ["image"] = image, ["text"] = p.text(frame, count), ["expiry"] = (frame.args["expiry"] or "") } } .. epilogue else return require('Module:Message box').main('ombox', { type = type_param, image = image, text = p.text(frame, count), expiry = (frame.args["expiry"] or "") }) .. epilogue end end return p 134551888e066954a89c109d2faa8af71a4454a4 มอดูล:Massage box/configuration 828 106 216 2023-10-06T17:45:40Z PeachFullzZ 2 สร้างหน้าด้วย "-------------------------------------------------------------------------------- -- Message box configuration -- -- -- -- This module contains configuration data for [[Module:Message box]]. -- -------------------------------------------------------------------------------- return { ambox = { types = { speedy = {..." Scribunto text/plain -------------------------------------------------------------------------------- -- Message box configuration -- -- -- -- This module contains configuration data for [[Module:Message box]]. -- -------------------------------------------------------------------------------- return { ambox = { types = { speedy = { class = 'ambox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'ambox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'ambox-content', image = 'Ambox important.svg' }, style = { class = 'ambox-style', image = 'Edit-clear.svg' }, move = { class = 'ambox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'ambox-protection', image = 'Semi-protection-shackle-keyhole.svg' }, notice = { class = 'ambox-notice', image = 'Information icon4.svg' } }, default = 'notice', allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden'}, allowSmall = true, smallParam = 'left', smallClass = 'mbox-small-left', substCheck = true, classes = {'metadata', 'ambox'}, imageEmptyCell = true, imageCheckBlank = true, imageSmallSize = '20x20px', imageCellDiv = true, useCollapsibleTextFields = true, imageRightNone = true, sectionDefault = 'article', allowMainspaceCategories = true, templateCategory = 'Article message templates', templateCategoryRequireName = true, templateErrorCategory = 'Article message templates with missing parameters', templateErrorParamsToCheck = {'issue', 'fix', 'subst'}, removalNotice = '<small>[[Help:Maintenance template removal|Learn how and when to remove this template message]]</small>', templatestyles = 'Module:Message box/ambox.css' }, cmbox = { types = { speedy = { class = 'cmbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'cmbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'cmbox-content', image = 'Ambox important.svg' }, style = { class = 'cmbox-style', image = 'Edit-clear.svg' }, move = { class = 'cmbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'cmbox-protection', image = 'Semi-protection-shackle-keyhole.svg' }, notice = { class = 'cmbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'cmbox'}, imageEmptyCell = true, templatestyles = 'Module:Message box/cmbox.css' }, fmbox = { types = { warning = { class = 'fmbox-warning', image = 'Ambox warning pn.svg' }, editnotice = { class = 'fmbox-editnotice', image = 'Information icon4.svg' }, system = { class = 'fmbox-system', image = 'Information icon4.svg' } }, default = 'system', showInvalidTypeError = true, classes = {'fmbox'}, imageEmptyCell = false, imageRightNone = false, templatestyles = 'Module:Message box/fmbox.css' }, imbox = { types = { speedy = { class = 'imbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'imbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'imbox-content', image = 'Ambox important.svg' }, style = { class = 'imbox-style', image = 'Edit-clear.svg' }, move = { class = 'imbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'imbox-protection', image = 'Semi-protection-shackle-keyhole.svg' }, license = { class = 'imbox-license licensetpl', image = 'Imbox-license.svg' }, featured = { class = 'imbox-featured', image = 'Cscr-featured.svg', imageNeedsLink = true }, notice = { class = 'imbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'imbox'}, imageEmptyCell = true, below = true, templateCategory = 'File message boxes', templatestyles = 'Module:Message box/imbox.css' }, ombox = { types = { speedy = { class = 'ombox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'ombox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'ombox-content', image = 'Ambox important.svg' }, style = { class = 'ombox-style', image = 'Edit-clear.svg' }, move = { class = 'ombox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'ombox-protection', image = 'Semi-protection-shackle-keyhole.svg' }, notice = { class = 'ombox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'ombox'}, allowSmall = true, imageEmptyCell = true, imageRightNone = true, templatestyles = 'Module:Message box/ombox.css' }, tmbox = { types = { speedy = { class = 'tmbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'tmbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'tmbox-content', image = 'Ambox important.svg' }, style = { class = 'tmbox-style', image = 'Edit-clear.svg' }, move = { class = 'tmbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'tmbox-protection', image = 'Semi-protection-shackle-keyhole.svg' }, notice = { class = 'tmbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'tmbox'}, allowSmall = true, imageRightNone = true, imageEmptyCell = true, templateCategory = 'Talk message boxes', templatestyles = 'Module:Message box/tmbox.css' } } 27f00af5cf3939613e9156acd5e62a3469d03d81 มอดูล:WPMILHIST Infobox style 828 107 217 2023-10-06T17:51:40Z PeachFullzZ 2 สร้างหน้าด้วย "local retval = { main_box_raw_auto_width = 'border-spacing:2px;', header_raw = 'background-color:#C3D6EF;text-align:center;vertical-align:middle;font-size:110%;', sub_header_raw = 'background-color:#DCDCDC;text-align:center;vertical-align:middle;', header_color = 'background-color:#C3D6EF;', nav_box = 'margin:0;float:right;clear:right;width:25.5em;margin-bottom:0.5em;margin-left:1em;', nav_box_child = 'margin:0;float:right;clear:right;width:25..." Scribunto text/plain local retval = { main_box_raw_auto_width = 'border-spacing:2px;', header_raw = 'background-color:#C3D6EF;text-align:center;vertical-align:middle;font-size:110%;', sub_header_raw = 'background-color:#DCDCDC;text-align:center;vertical-align:middle;', header_color = 'background-color:#C3D6EF;', nav_box = 'margin:0;float:right;clear:right;width:25.5em;margin-bottom:0.5em;margin-left:1em;', nav_box_child = 'margin:0;float:right;clear:right;width:25em;margin-bottom:0.5em;', nav_box_wide = '', nav_box_header = 'background-color:#C3D6EF;', nav_box_wide_header = 'background-color:#C3D6EF;', nav_box_label = 'background-color:#DCDCDC;', image_box_raw = 'text-align:center;border-bottom:1px solid #aaa;line-height:1.5em;', image_box_plain_raw = 'text-align:center;line-height:1.5em;', internal_border = '1px dotted #aaa;', section_border = '1px solid #aaa;' } retval.main_box_raw = 'width:25.5em;' .. retval.main_box_raw_auto_width retval.header_bar = 'style="' .. retval.header_raw .. '"' retval.sub_header_bar = 'style="' .. retval.sub_header_raw .. '"' retval.image_box = 'style="' .. retval.image_box_raw .. '"' retval.image_box_plain = 'style="' .. retval.image_box_plain_raw .. '"' return retval 0f9ea47bc17e40cdabbae6de54f63e40ae502f8e มอดูล:Navbar 828 108 218 2023-10-06T17:56:28Z PeachFullzZ 2 สร้างหน้าด้วย "local p = {} local cfg = mw.loadData('Module:Navbar/configuration') local function get_title_arg(is_collapsible, template) local title_arg = 1 if is_collapsible then title_arg = 2 end if template then title_arg = 'template' end return title_arg end local function choose_links(template, args) -- The show table indicates the default displayed items. -- view, talk, edit, hist, move, watch -- TODO: Move to configuration. local show = {true, tr..." Scribunto text/plain local p = {} local cfg = mw.loadData('Module:Navbar/configuration') local function get_title_arg(is_collapsible, template) local title_arg = 1 if is_collapsible then title_arg = 2 end if template then title_arg = 'template' end return title_arg end local function choose_links(template, args) -- The show table indicates the default displayed items. -- view, talk, edit, hist, move, watch -- TODO: Move to configuration. local show = {true, true, true, false, false, false} if template then show[2] = false show[3] = false local index = {t = 2, d = 2, e = 3, h = 4, m = 5, w = 6, talk = 2, edit = 3, hist = 4, move = 5, watch = 6} -- TODO: Consider removing TableTools dependency. for _, v in ipairs(require ('Module:TableTools').compressSparseArray(args)) do local num = index[v] if num then show[num] = true end end end local remove_edit_link = args.noedit if remove_edit_link then show[3] = false end return show end local function add_link(link_description, ul, is_mini, font_style) local l if link_description.url then l = {'[', '', ']'} else l = {'[[', '|', ']]'} end ul:tag('li') :addClass('nv-' .. link_description.full) :wikitext(l[1] .. link_description.link .. l[2]) :tag(is_mini and 'abbr' or 'span') :attr('title', link_description.html_title) :cssText(font_style) :wikitext(is_mini and link_description.mini or link_description.full) :done() :wikitext(l[3]) :done() end local function make_list(title_text, has_brackets, displayed_links, is_mini, font_style) local title = mw.title.new(mw.text.trim(title_text), cfg.title_namespace) if not title then error(cfg.invalid_title .. title_text) end local talkpage = title.talkPageTitle and title.talkPageTitle.fullText or '' -- TODO: Get link_descriptions and show into the configuration module. -- link_descriptions should be easier... local link_descriptions = { { ['mini'] = 'v', ['full'] = 'view', ['html_title'] = 'View this template', ['link'] = title.fullText, ['url'] = false }, { ['mini'] = 't', ['full'] = 'talk', ['html_title'] = 'Discuss this template', ['link'] = talkpage, ['url'] = false }, { ['mini'] = 'e', ['full'] = 'edit', ['html_title'] = 'Edit this template', ['link'] = title:fullUrl('action=edit'), ['url'] = true }, { ['mini'] = 'h', ['full'] = 'hist', ['html_title'] = 'History of this template', ['link'] = title:fullUrl('action=history'), ['url'] = true }, { ['mini'] = 'm', ['full'] = 'move', ['html_title'] = 'Move this template', ['link'] = mw.title.new('Special:Movepage'):fullUrl('target='..title.fullText), ['url'] = true }, { ['mini'] = 'w', ['full'] = 'watch', ['html_title'] = 'Watch this template', ['link'] = title:fullUrl('action=watch'), ['url'] = true } } local ul = mw.html.create('ul') if has_brackets then ul:addClass(cfg.classes.brackets) :cssText(font_style) end for i, _ in ipairs(displayed_links) do if displayed_links[i] then add_link(link_descriptions[i], ul, is_mini, font_style) end end return ul:done() end function p._navbar(args) -- TODO: We probably don't need both fontstyle and fontcolor... local font_style = args.fontstyle local font_color = args.fontcolor local is_collapsible = args.collapsible local is_mini = args.mini local is_plain = args.plain local collapsible_class = nil if is_collapsible then collapsible_class = cfg.classes.collapsible if not is_plain then is_mini = 1 end if font_color then font_style = (font_style or '') .. '; color: ' .. font_color .. ';' end end local navbar_style = args.style local div = mw.html.create():tag('div') div :addClass(cfg.classes.navbar) :addClass(cfg.classes.plainlinks) :addClass(cfg.classes.horizontal_list) :addClass(collapsible_class) -- we made the determination earlier :cssText(navbar_style) if is_mini then div:addClass(cfg.classes.mini) end local box_text = (args.text or cfg.box_text) .. ' ' -- the concatenated space guarantees the box text is separated if not (is_mini or is_plain) then div :tag('span') :addClass(cfg.classes.box_text) :cssText(font_style) :wikitext(box_text) end local template = args.template local displayed_links = choose_links(template, args) local has_brackets = args.brackets local title_arg = get_title_arg(is_collapsible, template) local title_text = args[title_arg] or (':' .. mw.getCurrentFrame():getParent():getTitle()) local list = make_list(title_text, has_brackets, displayed_links, is_mini, font_style) div:node(list) if is_collapsible then local title_text_class if is_mini then title_text_class = cfg.classes.collapsible_title_mini else title_text_class = cfg.classes.collapsible_title_full end div:done() :tag('div') :addClass(title_text_class) :cssText(font_style) :wikitext(args[1]) end local frame = mw.getCurrentFrame() -- hlist -> navbar is best-effort to preserve old Common.css ordering. return frame:extensionTag{ name = 'templatestyles', args = { src = cfg.hlist_templatestyles } } .. frame:extensionTag{ name = 'templatestyles', args = { src = cfg.templatestyles } } .. tostring(div:done()) end function p.navbar(frame) return p._navbar(require('Module:Arguments').getArgs(frame)) end return p 79f907e59eaa8bbf8dd50bb751933ebeaaa7eb17 219 218 2023-10-06T17:56:49Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Navbar]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local p = {} local cfg = mw.loadData('Module:Navbar/configuration') local function get_title_arg(is_collapsible, template) local title_arg = 1 if is_collapsible then title_arg = 2 end if template then title_arg = 'template' end return title_arg end local function choose_links(template, args) -- The show table indicates the default displayed items. -- view, talk, edit, hist, move, watch -- TODO: Move to configuration. local show = {true, true, true, false, false, false} if template then show[2] = false show[3] = false local index = {t = 2, d = 2, e = 3, h = 4, m = 5, w = 6, talk = 2, edit = 3, hist = 4, move = 5, watch = 6} -- TODO: Consider removing TableTools dependency. for _, v in ipairs(require ('Module:TableTools').compressSparseArray(args)) do local num = index[v] if num then show[num] = true end end end local remove_edit_link = args.noedit if remove_edit_link then show[3] = false end return show end local function add_link(link_description, ul, is_mini, font_style) local l if link_description.url then l = {'[', '', ']'} else l = {'[[', '|', ']]'} end ul:tag('li') :addClass('nv-' .. link_description.full) :wikitext(l[1] .. link_description.link .. l[2]) :tag(is_mini and 'abbr' or 'span') :attr('title', link_description.html_title) :cssText(font_style) :wikitext(is_mini and link_description.mini or link_description.full) :done() :wikitext(l[3]) :done() end local function make_list(title_text, has_brackets, displayed_links, is_mini, font_style) local title = mw.title.new(mw.text.trim(title_text), cfg.title_namespace) if not title then error(cfg.invalid_title .. title_text) end local talkpage = title.talkPageTitle and title.talkPageTitle.fullText or '' -- TODO: Get link_descriptions and show into the configuration module. -- link_descriptions should be easier... local link_descriptions = { { ['mini'] = 'v', ['full'] = 'view', ['html_title'] = 'View this template', ['link'] = title.fullText, ['url'] = false }, { ['mini'] = 't', ['full'] = 'talk', ['html_title'] = 'Discuss this template', ['link'] = talkpage, ['url'] = false }, { ['mini'] = 'e', ['full'] = 'edit', ['html_title'] = 'Edit this template', ['link'] = title:fullUrl('action=edit'), ['url'] = true }, { ['mini'] = 'h', ['full'] = 'hist', ['html_title'] = 'History of this template', ['link'] = title:fullUrl('action=history'), ['url'] = true }, { ['mini'] = 'm', ['full'] = 'move', ['html_title'] = 'Move this template', ['link'] = mw.title.new('Special:Movepage'):fullUrl('target='..title.fullText), ['url'] = true }, { ['mini'] = 'w', ['full'] = 'watch', ['html_title'] = 'Watch this template', ['link'] = title:fullUrl('action=watch'), ['url'] = true } } local ul = mw.html.create('ul') if has_brackets then ul:addClass(cfg.classes.brackets) :cssText(font_style) end for i, _ in ipairs(displayed_links) do if displayed_links[i] then add_link(link_descriptions[i], ul, is_mini, font_style) end end return ul:done() end function p._navbar(args) -- TODO: We probably don't need both fontstyle and fontcolor... local font_style = args.fontstyle local font_color = args.fontcolor local is_collapsible = args.collapsible local is_mini = args.mini local is_plain = args.plain local collapsible_class = nil if is_collapsible then collapsible_class = cfg.classes.collapsible if not is_plain then is_mini = 1 end if font_color then font_style = (font_style or '') .. '; color: ' .. font_color .. ';' end end local navbar_style = args.style local div = mw.html.create():tag('div') div :addClass(cfg.classes.navbar) :addClass(cfg.classes.plainlinks) :addClass(cfg.classes.horizontal_list) :addClass(collapsible_class) -- we made the determination earlier :cssText(navbar_style) if is_mini then div:addClass(cfg.classes.mini) end local box_text = (args.text or cfg.box_text) .. ' ' -- the concatenated space guarantees the box text is separated if not (is_mini or is_plain) then div :tag('span') :addClass(cfg.classes.box_text) :cssText(font_style) :wikitext(box_text) end local template = args.template local displayed_links = choose_links(template, args) local has_brackets = args.brackets local title_arg = get_title_arg(is_collapsible, template) local title_text = args[title_arg] or (':' .. mw.getCurrentFrame():getParent():getTitle()) local list = make_list(title_text, has_brackets, displayed_links, is_mini, font_style) div:node(list) if is_collapsible then local title_text_class if is_mini then title_text_class = cfg.classes.collapsible_title_mini else title_text_class = cfg.classes.collapsible_title_full end div:done() :tag('div') :addClass(title_text_class) :cssText(font_style) :wikitext(args[1]) end local frame = mw.getCurrentFrame() -- hlist -> navbar is best-effort to preserve old Common.css ordering. return frame:extensionTag{ name = 'templatestyles', args = { src = cfg.hlist_templatestyles } } .. frame:extensionTag{ name = 'templatestyles', args = { src = cfg.templatestyles } } .. tostring(div:done()) end function p.navbar(frame) return p._navbar(require('Module:Arguments').getArgs(frame)) end return p 79f907e59eaa8bbf8dd50bb751933ebeaaa7eb17 มอดูล:Template wrapper 828 109 220 2023-10-06T17:58:09Z PeachFullzZ 2 สร้างหน้าด้วย "require('strict'); local error_msg = '<span style=\"font-size:100%\" class=\"error\"><code style=\"color:inherit; border:inherit; padding:inherit;\">&#124;_template=</code> missing or empty</span>'; --[[--------------------------< I S _ I N _ T A B L E >-------------------------------------------------------- scan through tbl looking for value; return true if found, false else ]] local function is_in_table (tbl, value) for k, v in pairs (t..." Scribunto text/plain require('strict'); local error_msg = '<span style=\"font-size:100%\" class=\"error\"><code style=\"color:inherit; border:inherit; padding:inherit;\">&#124;_template=</code> missing or empty</span>'; --[[--------------------------< I S _ I N _ T A B L E >-------------------------------------------------------- scan through tbl looking for value; return true if found, false else ]] local function is_in_table (tbl, value) for k, v in pairs (tbl) do if v == value then return true end end return false; end --[[--------------------------< A D D _ P A R A M E T E R >---------------------------------------------------- adds parameter name and its value to args table according to the state of boolean list argument; kv pair for template execution; k=v string for template listing. ]] local function add_parameter (k, v, args, list) if list then table.insert( args, table.concat ({k, '=', v})); -- write parameter names and values to args table as string else args[k] = v; -- copy parameters to args table end end --[[--------------------------< A L I A S _ M A P _ G E T >---------------------------------------------------- returns a table of local template (parent frame) parameter names and the target template names that match where in [key]=<value> pairs where: [key] is local template parameter name (an alias) <value> is target template parameter name (the canonical parameter name used in the working template) The parameter |_alias-map= has the form: |_alias-map=<list> where <list> is a comma-separated list of alias / canonical parameter name pairs in the form <from> : <to> where: <from> is the local template's parameter name (alias) <to> is the target template's parameter name (canonical) for enumerated parameters place an octothorp (#) where the enumerator digits are placed in the parameter names: <from#> : <to#> ]] local function alias_map_get (_alias_map) local T = mw.text.split (_alias_map, '%s*,%s*'); -- convert the comma-separated list into a table of alias pairs local mapped_aliases = {}; -- mapped aliases will go here local l_name, t_name; -- parameter names for _, alias_pair in ipairs (T) do -- loop through the table of alias pairs l_name, t_name = alias_pair:match ('(.-)%s*:%s*(.+)'); -- from each pair, get local and target parameter names if l_name and t_name then -- if both are set if tonumber (l_name) then l_name = tonumber (l_name); -- convert number-as-text to a number end mapped_aliases[l_name] = t_name; -- add them to the map table end end return mapped_aliases; end --[[--------------------------< F R A M E _ A R G S _ G E T >-------------------------------------------------- Fetch the wrapper template's 'default' and control parameters; adds default parameters to args returns content of |_template= parameter (name of the working template); nil else ]] local function frame_args_get (frame_args, args, list) local template; for k, v in pairs (frame_args) do -- here we get the wrapper template's 'default' parameters if 'string' == type (k) and (v and ('' ~= v)) then -- do not pass along positional or empty parameters if '_template' == k then template = v; -- save the name of template that we are wrapping elseif '_exclude' ~= k and '_reuse' ~= k and '_include-positional' ~= k and '_alias-map' ~= k then -- these already handled so ignore here; add_parameter (k, v, args, list); -- add all other parameters to args in the style dictated by list end end end return template; -- return contents of |_template= parameter end --[=[--------------------------< P F R A M E _ A R G S _ G E T >------------------------------------------------ Fetches the wrapper template's 'live' parameters; adds live parameters that aren't members of the exclude table to args table; positional parameters may not be excluded no return value ]=] local function pframe_args_get (pframe_args, args, exclude, _include_positional, list) for k, v in pairs (pframe_args) do if 'string' == type (k) and not is_in_table (exclude, k) then -- do not pass along excluded parameters if v and ('' ~= v) then -- pass along only those parameters that have assigned values if 'unset' == v:lower() then -- special keyword to unset 'default' parameters set in the wrapper template v = ''; -- unset the value in the args table end add_parameter (k, v, args, list) -- add all other parameters to args in the style dictated by list; alias map only supported for local-template parameters end end end if _include_positional then for i, v in ipairs (pframe_args) do -- pass along positional parameters if 'unset' == v:lower() then -- special keyword to unset 'default' parameters set in the wrapper template v = ''; -- unset the value in the args table end add_parameter (i, v, args, list); end end end --[[--------------------------< _ M A I N >-------------------------------------------------------------------- Collect the various default and live parameters into args styled according to boolean list. returns name of the working or listed template or nil for an error message ]] local function _main (frame, args, list) local template; local exclude = {}; -- table of parameter names for parameters that are not passed to the working template local reuse_list = {}; -- table of pframe parameter names whose values are modified before they are passed to the working template as the same name local alias_map = {}; -- table that maps parameter aliases to working template canonical parameter names local _include_positional; if frame.args._exclude and ('' ~= frame.args._exclude) then -- if there is |_exclude= and it's not empty exclude = mw.text.split (frame.args._exclude, "%s*,%s*"); -- make a table from its contents end -- TODO: |_reuse= needs a better name (|_reuse=) if frame.args._reuse and ('' ~= frame.args._reuse) then -- if there is |_reuse= and it's not empty reuse_list = mw.text.split (frame.args._reuse, "%s*,%s*"); -- make a table from its contents end if frame.args['_alias-map'] and ('' ~= frame.args['_alias-map']) then -- if there is |_alias-map= and it's not empty alias_map = alias_map_get (frame.args['_alias-map']); -- make a table from its contents end template = frame_args_get (frame.args, args, list); -- get parameters provided in the {{#invoke:template wrapper|...|...}} if nil == template or '' == template then -- this is the one parameter that is required by this module return nil; -- not present, tell calling function to emit an error message end _include_positional = 'yes' == frame.args['_include-positional']; -- when true pass all positional parameters along with non-excluded named parameters to ... -- ... the working template; positional parameters are not excludable local _pframe_args = frame:getParent().args; -- here we get the wrapper template's 'live' parameters from pframe.args local pframe_args = {}; -- a local table that we can modify for k, v in pairs (_pframe_args) do -- make a copy that we can modify pframe_args[k] = v; end -- here we look for pframe parameters that are aliases of canonical parameter names; when found -- we replace the alias with the canonical. We do this here because the reuse_list works on -- canonical parameter names so first we convert alias parameter names to canonical names and then -- we remove those canonical names from the pframe table that are reused (provided to the working -- template through the frame args table) for k, v in pairs (alias_map) do -- k is alias name, v is canonical name if pframe_args[k] then -- if pframe_args has parameter with alias name pframe_args[v] = _pframe_args[k]; -- create new canonical name with alias' value pframe_args[k] = nil; -- unset the alias end end for k, v in pairs (pframe_args) do -- do enumerated parameter alias -> canonical translation if 'string' == type (k) then -- only named parameters can be enumerated if alias_map[k..'#'] then -- non-enumerated alias matches enumerated parameter pattern? enumerator at end only pframe_args[alias_map[k..'#']:gsub('#', '')] = v; -- remove '#' and copy parameter to pframe_args table pframe_args[k] = nil; -- unset the alias elseif k:match ('%d+') then -- if this parameter name contains digits local temp = k:gsub ('%d+', '#'); -- make a copy; digits replaced with single '#' local enum = k:match ('%d+'); -- get the enumerator if alias_map[temp] then -- if this parameter is a recognized enumerated alias pframe_args[alias_map[temp]:gsub('#', enum)] = v; -- use canonical name and replace '#' with enumerator and add to pframe_args pframe_args[k] = nil; -- unset the alias end end end end -- pframe parameters that are _reused are 'reused' have the form something like this: -- |chapter=[[wikisource:{{{chapter}}}|{{{chapter}}}]] -- where a parameter in the wrapping template is modified and then passed to the working template -- using the same parameter name (in this example |chapter=) -- remove parameters that will be reused for k, v in ipairs (reuse_list) do -- k is numerical index, v is canonical parameter name to ignore if pframe_args[v] then -- if pframe_args has parameter that should be ignored pframe_args[v] = nil; -- unset the ignored parameter end end pframe_args_get (pframe_args, args, exclude, _include_positional, list); -- add parameters and values to args that are not listed in the exclude table return template; -- args now has all default and live parameters, return working template name end --[[--------------------------< W R A P >---------------------------------------------------------------------- Template entry point. Call this function to 'execute' the working template ]] local function wrap (frame) local args = {}; -- table of default and live parameters and their values to be passed to the wrapped template local template; -- the name of the working template template = _main (frame, args, false); -- get default and live parameters and the name of the working template if not template then -- template name is required return error_msg; -- emit error message and abandon if template name not present end return frame:expandTemplate {title=template, args=args}; -- render the working template end --[[--------------------------< L I S T >---------------------------------------------------------------------- Template entry point. Call this function to 'display' the source for the working template. This function added as a result of a TfD here: Wikipedia:Templates_for_discussion/Log/2018_April_28#Module:PassArguments This function replaces a similarly named function which was used in {{cite compare}} and {{cite compare2}} Values in the args table are numerically indexed strings in the form 'name=value' ]] local function list(frame, do_link) local args = {}; -- table of default and live parameters and their values to be passed to the listed template local template; -- the name of the listed template template = _main (frame, args, true); -- get default and live parameters and the name of the listed template if not template then -- template name is required return error_msg; -- emit error message and abandon if template name not present end if do_link then template = ('[[%s|%s]]'):format(frame:expandTemplate{ title='Transclude', args = {template} }, template) end table.sort(args) for i = 1, #args do local stripped = args[i]:match('^' .. i .. '=([^=]*)$') if stripped then args[i] = stripped else break end end return frame:preprocess(table.concat({ '<code style="color:inherit; background:inherit; border:none;">&#123;&#123;', template, ('<wbr><nowiki>|%s</nowiki>'):rep(#args):format(unpack(args)), '&#125;&#125;</code>'})); -- render the template end local function link (frame) return list(frame, true) end --[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------ ]] return { link = link, list = list, wrap = wrap, }; 5e3d3ed3f3988725fb0fef6b44479bacc4210f37 221 220 2023-10-06T17:58:21Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Template wrapper]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain require('strict'); local error_msg = '<span style=\"font-size:100%\" class=\"error\"><code style=\"color:inherit; border:inherit; padding:inherit;\">&#124;_template=</code> missing or empty</span>'; --[[--------------------------< I S _ I N _ T A B L E >-------------------------------------------------------- scan through tbl looking for value; return true if found, false else ]] local function is_in_table (tbl, value) for k, v in pairs (tbl) do if v == value then return true end end return false; end --[[--------------------------< A D D _ P A R A M E T E R >---------------------------------------------------- adds parameter name and its value to args table according to the state of boolean list argument; kv pair for template execution; k=v string for template listing. ]] local function add_parameter (k, v, args, list) if list then table.insert( args, table.concat ({k, '=', v})); -- write parameter names and values to args table as string else args[k] = v; -- copy parameters to args table end end --[[--------------------------< A L I A S _ M A P _ G E T >---------------------------------------------------- returns a table of local template (parent frame) parameter names and the target template names that match where in [key]=<value> pairs where: [key] is local template parameter name (an alias) <value> is target template parameter name (the canonical parameter name used in the working template) The parameter |_alias-map= has the form: |_alias-map=<list> where <list> is a comma-separated list of alias / canonical parameter name pairs in the form <from> : <to> where: <from> is the local template's parameter name (alias) <to> is the target template's parameter name (canonical) for enumerated parameters place an octothorp (#) where the enumerator digits are placed in the parameter names: <from#> : <to#> ]] local function alias_map_get (_alias_map) local T = mw.text.split (_alias_map, '%s*,%s*'); -- convert the comma-separated list into a table of alias pairs local mapped_aliases = {}; -- mapped aliases will go here local l_name, t_name; -- parameter names for _, alias_pair in ipairs (T) do -- loop through the table of alias pairs l_name, t_name = alias_pair:match ('(.-)%s*:%s*(.+)'); -- from each pair, get local and target parameter names if l_name and t_name then -- if both are set if tonumber (l_name) then l_name = tonumber (l_name); -- convert number-as-text to a number end mapped_aliases[l_name] = t_name; -- add them to the map table end end return mapped_aliases; end --[[--------------------------< F R A M E _ A R G S _ G E T >-------------------------------------------------- Fetch the wrapper template's 'default' and control parameters; adds default parameters to args returns content of |_template= parameter (name of the working template); nil else ]] local function frame_args_get (frame_args, args, list) local template; for k, v in pairs (frame_args) do -- here we get the wrapper template's 'default' parameters if 'string' == type (k) and (v and ('' ~= v)) then -- do not pass along positional or empty parameters if '_template' == k then template = v; -- save the name of template that we are wrapping elseif '_exclude' ~= k and '_reuse' ~= k and '_include-positional' ~= k and '_alias-map' ~= k then -- these already handled so ignore here; add_parameter (k, v, args, list); -- add all other parameters to args in the style dictated by list end end end return template; -- return contents of |_template= parameter end --[=[--------------------------< P F R A M E _ A R G S _ G E T >------------------------------------------------ Fetches the wrapper template's 'live' parameters; adds live parameters that aren't members of the exclude table to args table; positional parameters may not be excluded no return value ]=] local function pframe_args_get (pframe_args, args, exclude, _include_positional, list) for k, v in pairs (pframe_args) do if 'string' == type (k) and not is_in_table (exclude, k) then -- do not pass along excluded parameters if v and ('' ~= v) then -- pass along only those parameters that have assigned values if 'unset' == v:lower() then -- special keyword to unset 'default' parameters set in the wrapper template v = ''; -- unset the value in the args table end add_parameter (k, v, args, list) -- add all other parameters to args in the style dictated by list; alias map only supported for local-template parameters end end end if _include_positional then for i, v in ipairs (pframe_args) do -- pass along positional parameters if 'unset' == v:lower() then -- special keyword to unset 'default' parameters set in the wrapper template v = ''; -- unset the value in the args table end add_parameter (i, v, args, list); end end end --[[--------------------------< _ M A I N >-------------------------------------------------------------------- Collect the various default and live parameters into args styled according to boolean list. returns name of the working or listed template or nil for an error message ]] local function _main (frame, args, list) local template; local exclude = {}; -- table of parameter names for parameters that are not passed to the working template local reuse_list = {}; -- table of pframe parameter names whose values are modified before they are passed to the working template as the same name local alias_map = {}; -- table that maps parameter aliases to working template canonical parameter names local _include_positional; if frame.args._exclude and ('' ~= frame.args._exclude) then -- if there is |_exclude= and it's not empty exclude = mw.text.split (frame.args._exclude, "%s*,%s*"); -- make a table from its contents end -- TODO: |_reuse= needs a better name (|_reuse=) if frame.args._reuse and ('' ~= frame.args._reuse) then -- if there is |_reuse= and it's not empty reuse_list = mw.text.split (frame.args._reuse, "%s*,%s*"); -- make a table from its contents end if frame.args['_alias-map'] and ('' ~= frame.args['_alias-map']) then -- if there is |_alias-map= and it's not empty alias_map = alias_map_get (frame.args['_alias-map']); -- make a table from its contents end template = frame_args_get (frame.args, args, list); -- get parameters provided in the {{#invoke:template wrapper|...|...}} if nil == template or '' == template then -- this is the one parameter that is required by this module return nil; -- not present, tell calling function to emit an error message end _include_positional = 'yes' == frame.args['_include-positional']; -- when true pass all positional parameters along with non-excluded named parameters to ... -- ... the working template; positional parameters are not excludable local _pframe_args = frame:getParent().args; -- here we get the wrapper template's 'live' parameters from pframe.args local pframe_args = {}; -- a local table that we can modify for k, v in pairs (_pframe_args) do -- make a copy that we can modify pframe_args[k] = v; end -- here we look for pframe parameters that are aliases of canonical parameter names; when found -- we replace the alias with the canonical. We do this here because the reuse_list works on -- canonical parameter names so first we convert alias parameter names to canonical names and then -- we remove those canonical names from the pframe table that are reused (provided to the working -- template through the frame args table) for k, v in pairs (alias_map) do -- k is alias name, v is canonical name if pframe_args[k] then -- if pframe_args has parameter with alias name pframe_args[v] = _pframe_args[k]; -- create new canonical name with alias' value pframe_args[k] = nil; -- unset the alias end end for k, v in pairs (pframe_args) do -- do enumerated parameter alias -> canonical translation if 'string' == type (k) then -- only named parameters can be enumerated if alias_map[k..'#'] then -- non-enumerated alias matches enumerated parameter pattern? enumerator at end only pframe_args[alias_map[k..'#']:gsub('#', '')] = v; -- remove '#' and copy parameter to pframe_args table pframe_args[k] = nil; -- unset the alias elseif k:match ('%d+') then -- if this parameter name contains digits local temp = k:gsub ('%d+', '#'); -- make a copy; digits replaced with single '#' local enum = k:match ('%d+'); -- get the enumerator if alias_map[temp] then -- if this parameter is a recognized enumerated alias pframe_args[alias_map[temp]:gsub('#', enum)] = v; -- use canonical name and replace '#' with enumerator and add to pframe_args pframe_args[k] = nil; -- unset the alias end end end end -- pframe parameters that are _reused are 'reused' have the form something like this: -- |chapter=[[wikisource:{{{chapter}}}|{{{chapter}}}]] -- where a parameter in the wrapping template is modified and then passed to the working template -- using the same parameter name (in this example |chapter=) -- remove parameters that will be reused for k, v in ipairs (reuse_list) do -- k is numerical index, v is canonical parameter name to ignore if pframe_args[v] then -- if pframe_args has parameter that should be ignored pframe_args[v] = nil; -- unset the ignored parameter end end pframe_args_get (pframe_args, args, exclude, _include_positional, list); -- add parameters and values to args that are not listed in the exclude table return template; -- args now has all default and live parameters, return working template name end --[[--------------------------< W R A P >---------------------------------------------------------------------- Template entry point. Call this function to 'execute' the working template ]] local function wrap (frame) local args = {}; -- table of default and live parameters and their values to be passed to the wrapped template local template; -- the name of the working template template = _main (frame, args, false); -- get default and live parameters and the name of the working template if not template then -- template name is required return error_msg; -- emit error message and abandon if template name not present end return frame:expandTemplate {title=template, args=args}; -- render the working template end --[[--------------------------< L I S T >---------------------------------------------------------------------- Template entry point. Call this function to 'display' the source for the working template. This function added as a result of a TfD here: Wikipedia:Templates_for_discussion/Log/2018_April_28#Module:PassArguments This function replaces a similarly named function which was used in {{cite compare}} and {{cite compare2}} Values in the args table are numerically indexed strings in the form 'name=value' ]] local function list(frame, do_link) local args = {}; -- table of default and live parameters and their values to be passed to the listed template local template; -- the name of the listed template template = _main (frame, args, true); -- get default and live parameters and the name of the listed template if not template then -- template name is required return error_msg; -- emit error message and abandon if template name not present end if do_link then template = ('[[%s|%s]]'):format(frame:expandTemplate{ title='Transclude', args = {template} }, template) end table.sort(args) for i = 1, #args do local stripped = args[i]:match('^' .. i .. '=([^=]*)$') if stripped then args[i] = stripped else break end end return frame:preprocess(table.concat({ '<code style="color:inherit; background:inherit; border:none;">&#123;&#123;', template, ('<wbr><nowiki>|%s</nowiki>'):rep(#args):format(unpack(args)), '&#125;&#125;</code>'})); -- render the template end local function link (frame) return list(frame, true) end --[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------ ]] return { link = link, list = list, wrap = wrap, }; 5e3d3ed3f3988725fb0fef6b44479bacc4210f37 มอดูล:I18n 828 110 222 2023-10-06T17:59:39Z PeachFullzZ 2 สร้างหน้าด้วย "local p = {} -- Credit to http://stackoverflow.com/a/1283608/2644759 -- cc-by-sa 3.0 local function tableMerge(t1, t2, overwrite) for k,v in pairs(t2) do if type(v) == "table" and type(t1[k]) == "table" then -- since type(t1[k]) == type(v) == "table", so t1[k] and v is true tableMerge(t1[k], v, overwrite) -- t2[k] == v else if overwrite or t1[k] == nil then t1[k] = v end end end return t1 end function p.loadI18n(name, i18n_arg)..." Scribunto text/plain local p = {} -- Credit to http://stackoverflow.com/a/1283608/2644759 -- cc-by-sa 3.0 local function tableMerge(t1, t2, overwrite) for k,v in pairs(t2) do if type(v) == "table" and type(t1[k]) == "table" then -- since type(t1[k]) == type(v) == "table", so t1[k] and v is true tableMerge(t1[k], v, overwrite) -- t2[k] == v else if overwrite or t1[k] == nil then t1[k] = v end end end return t1 end function p.loadI18n(name, i18n_arg) local exist, res = pcall(require, name) if exist and next(res) ~= nil then if i18n_arg then tableMerge(i18n_arg, res.i18n, true) elseif type(i18n) == "table" then -- merge to global i18n tableMerge(i18n, res.i18n, true) end end end function p.loadI18nFrame(frame, i18n_arg) p.loadI18n(frame:getTitle().."/i18n", i18n_arg) end return p d9eee84d5b15b40c416d3981a6a221f9df086052 223 222 2023-10-06T17:59:50Z PeachFullzZ 2 ป้องกัน "[[มอดูล:I18n]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain local p = {} -- Credit to http://stackoverflow.com/a/1283608/2644759 -- cc-by-sa 3.0 local function tableMerge(t1, t2, overwrite) for k,v in pairs(t2) do if type(v) == "table" and type(t1[k]) == "table" then -- since type(t1[k]) == type(v) == "table", so t1[k] and v is true tableMerge(t1[k], v, overwrite) -- t2[k] == v else if overwrite or t1[k] == nil then t1[k] = v end end end return t1 end function p.loadI18n(name, i18n_arg) local exist, res = pcall(require, name) if exist and next(res) ~= nil then if i18n_arg then tableMerge(i18n_arg, res.i18n, true) elseif type(i18n) == "table" then -- merge to global i18n tableMerge(i18n, res.i18n, true) end end end function p.loadI18nFrame(frame, i18n_arg) p.loadI18n(frame:getTitle().."/i18n", i18n_arg) end return p d9eee84d5b15b40c416d3981a6a221f9df086052 แม่แบบ:Parameter names example 10 111 224 2023-10-06T18:17:24Z PeachFullzZ 2 สร้างหน้าด้วย "<includeonly>{{#invoke:Parameter names example|main}}</includeonly><noinclude> {{Documentation}} </noinclude>" wikitext text/x-wiki <includeonly>{{#invoke:Parameter names example|main}}</includeonly><noinclude> {{Documentation}} </noinclude> de1e29d6ebc113e9d1649ea6a976625885db8a2f มอดูล:Parameter names example 828 112 225 2023-10-06T18:18:19Z PeachFullzZ 2 สร้างหน้าด้วย "-- This module implements {{parameter names example}}. local p = {} local function makeParam(s) local lb = '&#123;' local rb = '&#125;' return lb:rep(3) .. s .. rb:rep(3) end local function italicize(s) return "''" .. s .. "''" end local function plain(s) return s end function p._main(args, frame) -- Find how we want to format the arguments to the template. local formatFunc if args._display == 'italics' or args._display == 'italic' then..." Scribunto text/plain -- This module implements {{parameter names example}}. local p = {} local function makeParam(s) local lb = '&#123;' local rb = '&#125;' return lb:rep(3) .. s .. rb:rep(3) end local function italicize(s) return "''" .. s .. "''" end local function plain(s) return s end function p._main(args, frame) -- Find how we want to format the arguments to the template. local formatFunc if args._display == 'italics' or args._display == 'italic' then formatFunc = italicize elseif args._display == 'plain' then formatFunc = plain else formatFunc = makeParam end -- Build the table of template arguments. local targs = {} for k, v in pairs(args) do if type(k) == 'number' then targs[v] = formatFunc(v) elseif not k:find('^_') then targs[k] = v end end --targs['nocat'] = 'yes'; --targs['categories'] = 'no'; --targs['demo'] = 'yes'; -- Find the template name. local template if args._template then template = args._template else local currentTitle = mw.title.getCurrentTitle() if currentTitle.prefixedText:find('/sandbox$') then template = currentTitle.prefixedText else template = currentTitle.basePageTitle.prefixedText end end -- Call the template with the arguments. frame = frame or mw.getCurrentFrame() local success, result = pcall( frame.expandTemplate, frame, {title = template, args = targs} ) if success then return result else return '' end end function p.main(frame) local args = require('Module:Arguments').getArgs(frame, { wrappers = 'Template:Parameter names example' }) return p._main(args, frame) end return p fdf94fb7a5dc1fabf118d60488a02f1e65b0df24 226 225 2023-10-06T18:18:32Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Parameter names example]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain -- This module implements {{parameter names example}}. local p = {} local function makeParam(s) local lb = '&#123;' local rb = '&#125;' return lb:rep(3) .. s .. rb:rep(3) end local function italicize(s) return "''" .. s .. "''" end local function plain(s) return s end function p._main(args, frame) -- Find how we want to format the arguments to the template. local formatFunc if args._display == 'italics' or args._display == 'italic' then formatFunc = italicize elseif args._display == 'plain' then formatFunc = plain else formatFunc = makeParam end -- Build the table of template arguments. local targs = {} for k, v in pairs(args) do if type(k) == 'number' then targs[v] = formatFunc(v) elseif not k:find('^_') then targs[k] = v end end --targs['nocat'] = 'yes'; --targs['categories'] = 'no'; --targs['demo'] = 'yes'; -- Find the template name. local template if args._template then template = args._template else local currentTitle = mw.title.getCurrentTitle() if currentTitle.prefixedText:find('/sandbox$') then template = currentTitle.prefixedText else template = currentTitle.basePageTitle.prefixedText end end -- Call the template with the arguments. frame = frame or mw.getCurrentFrame() local success, result = pcall( frame.expandTemplate, frame, {title = template, args = targs} ) if success then return result else return '' end end function p.main(frame) local args = require('Module:Arguments').getArgs(frame, { wrappers = 'Template:Parameter names example' }) return p._main(args, frame) end return p fdf94fb7a5dc1fabf118d60488a02f1e65b0df24 มอดูล:Navbar/configuration 828 113 227 2023-10-06T18:28:20Z PeachFullzZ 2 สร้างหน้าด้วย "return { ['templatestyles'] = 'Module:Navbar/styles.css', ['hlist_templatestyles'] = 'Hlist/styles.css', ['box_text'] = 'This box: ', -- default text box when not plain or mini ['title_namespace'] = 'Template', -- namespace to default to for title ['invalid_title'] = 'Invalid title ', ['classes'] = { -- set a line to nil if you don't want it ['navbar'] = 'navbar', ['plainlinks'] = 'plainlinks', -- plainlinks ['horizontal_list'] = 'hli..." Scribunto text/plain return { ['templatestyles'] = 'Module:Navbar/styles.css', ['hlist_templatestyles'] = 'Hlist/styles.css', ['box_text'] = 'This box: ', -- default text box when not plain or mini ['title_namespace'] = 'Template', -- namespace to default to for title ['invalid_title'] = 'Invalid title ', ['classes'] = { -- set a line to nil if you don't want it ['navbar'] = 'navbar', ['plainlinks'] = 'plainlinks', -- plainlinks ['horizontal_list'] = 'hlist', -- horizontal list class ['mini'] = 'navbar-mini', -- class indicating small links in the navbar ['this_box'] = 'navbar-boxtext', ['brackets'] = 'navbar-brackets', -- 'collapsible' is the key for a class to indicate the navbar is -- setting up the collapsible element in addition to the normal -- navbar. ['collapsible'] = 'navbar-collapse', ['collapsible_title_mini'] = 'navbar-ct-mini', ['collapsible_title_full'] = 'navbar-ct-full' } } b007c336b17ec4bcd4d5a9dca9f8cba301662b55 228 227 2023-10-06T18:28:35Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Navbar/configuration]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) Scribunto text/plain return { ['templatestyles'] = 'Module:Navbar/styles.css', ['hlist_templatestyles'] = 'Hlist/styles.css', ['box_text'] = 'This box: ', -- default text box when not plain or mini ['title_namespace'] = 'Template', -- namespace to default to for title ['invalid_title'] = 'Invalid title ', ['classes'] = { -- set a line to nil if you don't want it ['navbar'] = 'navbar', ['plainlinks'] = 'plainlinks', -- plainlinks ['horizontal_list'] = 'hlist', -- horizontal list class ['mini'] = 'navbar-mini', -- class indicating small links in the navbar ['this_box'] = 'navbar-boxtext', ['brackets'] = 'navbar-brackets', -- 'collapsible' is the key for a class to indicate the navbar is -- setting up the collapsible element in addition to the normal -- navbar. ['collapsible'] = 'navbar-collapse', ['collapsible_title_mini'] = 'navbar-ct-mini', ['collapsible_title_full'] = 'navbar-ct-full' } } b007c336b17ec4bcd4d5a9dca9f8cba301662b55 มอดูล:Navbar/styles.css 828 114 229 2023-10-06T18:30:55Z PeachFullzZ 2 สร้างหน้าด้วย "/* {{pp|small=yes}} */ .navbar { display: inline; font-size: 88%; font-weight: normal; } .navbar-collapse { float: left; text-align: left; } .navbar-boxtext { word-spacing: 0; } .navbar ul { display: inline-block; white-space: nowrap; line-height: inherit; } .navbar-brackets::before { margin-right: -0.125em; content: '[ '; } .navbar-brackets::after { margin-left: -0.125em; content: ' ]'; } .navbar li { word-spacing: -0.125em; }..." sanitized-css text/css /* {{pp|small=yes}} */ .navbar { display: inline; font-size: 88%; font-weight: normal; } .navbar-collapse { float: left; text-align: left; } .navbar-boxtext { word-spacing: 0; } .navbar ul { display: inline-block; white-space: nowrap; line-height: inherit; } .navbar-brackets::before { margin-right: -0.125em; content: '[ '; } .navbar-brackets::after { margin-left: -0.125em; content: ' ]'; } .navbar li { word-spacing: -0.125em; } .navbar a > span, .navbar a > abbr { text-decoration: inherit; } .navbar-mini abbr { font-variant: small-caps; border-bottom: none; text-decoration: none; cursor: inherit; } .navbar-ct-full { font-size: 114%; margin: 0 7em; } .navbar-ct-mini { font-size: 114%; margin: 0 4em; } 9d4056f949b4f0b159e3d40dfb1a5f01e72f9571 230 229 2023-10-06T18:31:10Z PeachFullzZ 2 ป้องกัน "[[มอดูล:Navbar/styles.css]]" แล้ว ([แก้ไข:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด) [ย้าย:อนุญาตเฉพาะผู้ดูแลระบบ] (ไม่มีกำหนด)) sanitized-css text/css /* {{pp|small=yes}} */ .navbar { display: inline; font-size: 88%; font-weight: normal; } .navbar-collapse { float: left; text-align: left; } .navbar-boxtext { word-spacing: 0; } .navbar ul { display: inline-block; white-space: nowrap; line-height: inherit; } .navbar-brackets::before { margin-right: -0.125em; content: '[ '; } .navbar-brackets::after { margin-left: -0.125em; content: ' ]'; } .navbar li { word-spacing: -0.125em; } .navbar a > span, .navbar a > abbr { text-decoration: inherit; } .navbar-mini abbr { font-variant: small-caps; border-bottom: none; text-decoration: none; cursor: inherit; } .navbar-ct-full { font-size: 114%; margin: 0 7em; } .navbar-ct-mini { font-size: 114%; margin: 0 4em; } 9d4056f949b4f0b159e3d40dfb1a5f01e72f9571 พูดคุย:หน้าหลัก 1 115 231 2023-10-21T10:57:37Z Sirikon 3 /* ภาษาของบทความ */ ส่วนใหม่ wikitext text/x-wiki == ภาษาของบทความ == นี่เป็นภาษาอังกฤษ [[ผู้ใช้:Sirikon|Sirikon]] ([[คุยกับผู้ใช้:Sirikon|คุย]]) 10:57, 21 ตุลาคม 2566 (UTC) 36ec292c833fbcd0d065748e349917011159da33